opencami 1.8.13 → 1.9.1
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 +4 -2
- package/dist/client/assets/{CSPContext-DATmz4sz.js → CSPContext-B3PAVjBL.js} +1 -1
- package/dist/client/assets/{DirectionContext-FHFKdJq_.js → DirectionContext-CR5CCisG.js} +1 -1
- package/dist/client/assets/_sessionKey-Bg_9uype.js +23 -0
- package/dist/client/assets/agents-BiTHBb6Z.js +2 -0
- package/dist/client/assets/{agents-screen-C58VLjES.js → agents-screen--ZMzN5cB.js} +1 -1
- package/dist/client/assets/bots-DxhRnQp5.js +2 -0
- package/dist/client/assets/{bots-screen-B8h4Y1VL.js → bots-screen-C_uJBNwI.js} +1 -1
- package/dist/client/assets/{button-BcUmP7JL.js → button-BciDmec0.js} +1 -1
- package/dist/client/assets/{composite--BBbKdxm.js → composite-DArWbFHm.js} +1 -1
- package/dist/client/assets/{connect-BmwKnEFP.js → connect-B48HecjN.js} +1 -1
- package/dist/client/assets/{dashboard-BWQl_-2-.js → dashboard-BVKx9FMy.js} +1 -1
- package/dist/client/assets/{event-BxzjTPjG.js → event-BCwqPPkP.js} +1 -1
- package/dist/client/assets/{file-explorer-screen-BAbbb_R4.js → file-explorer-screen-DPs-FWeA.js} +1 -1
- package/dist/client/assets/files-SEycwYCa.js +2 -0
- package/dist/client/assets/{follow-up-suggestions-Bq-xR5GV.js → follow-up-suggestions-BPjWBpiy.js} +1 -1
- package/dist/client/assets/{index-rOr2i8gW.js → index-0gdwm1_H.js} +1 -1
- package/dist/client/assets/{index-BTtT4Vbb.js → index-CGeJcqZ3.js} +1 -1
- package/dist/client/assets/{keyboard-shortcuts-dialog-BA8cBwWm.js → keyboard-shortcuts-dialog-CK_XTzLr.js} +1 -1
- package/dist/client/assets/{main-_1IghVZn.js → main-B2CrcRuC.js} +3 -3
- package/dist/client/assets/{markdown-CqIcraPO.js → markdown-CdkuX06F.js} +1 -1
- package/dist/client/assets/memory-C7lKdkmc.js +2 -0
- package/dist/client/assets/{memory-screen-GBzowsnE.js → memory-screen-C1RfLy-d.js} +1 -1
- package/dist/client/assets/{menu--FXN_JCl.js → menu-CIwnliij.js} +1 -1
- package/dist/client/assets/{opencami-logo-BFo87CeM.js → opencami-logo-SVuYD55V.js} +1 -1
- package/dist/client/assets/{proxy-CJ6-TEKD.js → proxy-BijR8W1L.js} +1 -1
- package/dist/client/assets/{react-BRYbnjMp.js → react-DWx7OvUo.js} +1 -1
- package/dist/client/assets/{search-dialog-CJS2GUnE.js → search-dialog-CB4KE8ec.js} +1 -1
- package/dist/client/assets/{search-sources-badge-D0YArqfp.js → search-sources-badge-B8Z-8sSf.js} +1 -1
- package/dist/client/assets/{session-export-dialog-Bc9YEPLs.js → session-export-dialog-tDiFuv3a.js} +1 -1
- package/dist/client/assets/{settings-dialog-SDzqDXsx.js → settings-dialog-aL-AH4Rt.js} +1 -1
- package/dist/client/assets/skills-D1T6uemU.js +2 -0
- package/dist/client/assets/{skills-panel-DIalYvpW.js → skills-panel-fjJQVMog.js} +1 -1
- package/dist/client/assets/styles-D0L88B64.css +1 -0
- package/dist/client/assets/{switch-BwmDNR0d.js → switch-Bn5uei2k.js} +1 -1
- package/dist/client/assets/{tabs-T1fJbUsm.js → tabs-DOBNAUVE.js} +1 -1
- package/dist/client/assets/{thinking-DUdE6Iej.js → thinking-dfGrFAMV.js} +1 -1
- package/dist/client/assets/{tooltip-DexBPu8g.js → tooltip-DOKkNFvu.js} +1 -1
- package/dist/client/assets/{use-file-explorer-state-eXs92yKN.js → use-file-explorer-state-BAa6Cxyr.js} +1 -1
- package/dist/client/assets/{useBaseUiId-DN9cOflS.js → useBaseUiId-DFpBD0sg.js} +1 -1
- package/dist/client/assets/{useCompositeItem-B_J-cnZX.js → useCompositeItem-B-Axq9-D.js} +1 -1
- package/dist/client/assets/{useControlled-DeDLOsPR.js → useControlled-CQHE0ITz.js} +1 -1
- package/dist/client/assets/{useMutation-TzgejsE_.js → useMutation-BFl-7GnD.js} +1 -1
- package/dist/client/assets/{useOnFirstRender-S4-xcV93.js → useOnFirstRender-DlXHIIGk.js} +1 -1
- package/dist/client/assets/{useQuery-BdjM5kzn.js → useQuery-D-sF8Tld.js} +1 -1
- package/dist/server/assets/{_sessionKey-DBzlGMo3.js → _sessionKey-D8TGrDRM.js} +429 -131
- package/dist/server/assets/{_tanstack-start-manifest_v-CX4xb59U.js → _tanstack-start-manifest_v-DalBo2bY.js} +1 -1
- package/dist/server/assets/{follow-up-suggestions-BmSFSY87.js → follow-up-suggestions-C65ptDij.js} +2 -2
- package/dist/server/assets/{index-C1dylvu-.js → index-gRco4Ina.js} +1 -1
- package/dist/server/assets/{router-CL6A11qi.js → router-DaKDqc9w.js} +72 -251
- package/dist/server/assets/{search-dialog-D8DvpPZw.js → search-dialog-DSSK93kq.js} +2 -2
- package/dist/server/assets/{settings-dialog-CeP-J_NJ.js → settings-dialog-DyWNblva.js} +2 -2
- package/dist/server/assets/{thinking-ClIWjSbx.js → thinking-CU0FRlzT.js} +2 -2
- package/dist/server/server.js +2 -2
- package/package.json +1 -1
- package/dist/client/assets/_sessionKey-D2ZMdqJ0.js +0 -23
- package/dist/client/assets/agents-9A0buuwT.js +0 -2
- package/dist/client/assets/bots-Lqt92ma0.js +0 -2
- package/dist/client/assets/files-DvIFms9G.js +0 -2
- package/dist/client/assets/memory-B3LyVZwO.js +0 -2
- package/dist/client/assets/skills-BVLjvrPU.js +0 -2
- package/dist/client/assets/styles-b2XYKZYx.css +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const tsrStartManifest = () => ({ "routes": { "__root__": { "filePath": "/root/opencami/src/routes/__root.tsx", "children": ["/", "/agents", "/bots", "/connect", "/dashboard", "/files", "/memory", "/new", "/skills", "/api/agents", "/api/cron", "/api/follow-ups", "/api/history", "/api/llm-features", "/api/models", "/api/paths", "/api/personas", "/api/ping", "/api/send", "/api/sessions", "/api/skills", "/api/stream", "/api/stt", "/api/tts", "/chat/$sessionKey", "/api/dashboard/crons", "/api/dashboard/gateway", "/api/dashboard/system", "/api/files/delete", "/api/files/download", "/api/files/info", "/api/files/list", "/api/files/mkdir", "/api/files/read", "/api/files/rename", "/api/files/save", "/api/files/upload"], "preloads": ["/assets/main-
|
|
1
|
+
const tsrStartManifest = () => ({ "routes": { "__root__": { "filePath": "/root/opencami/src/routes/__root.tsx", "children": ["/", "/agents", "/bots", "/connect", "/dashboard", "/files", "/memory", "/new", "/skills", "/api/agents", "/api/cron", "/api/follow-ups", "/api/history", "/api/llm-features", "/api/models", "/api/paths", "/api/personas", "/api/ping", "/api/send", "/api/sessions", "/api/skills", "/api/stream", "/api/stt", "/api/tts", "/chat/$sessionKey", "/api/dashboard/crons", "/api/dashboard/gateway", "/api/dashboard/system", "/api/files/delete", "/api/files/download", "/api/files/info", "/api/files/list", "/api/files/mkdir", "/api/files/read", "/api/files/rename", "/api/files/save", "/api/files/upload"], "preloads": ["/assets/main-B2CrcRuC.js"], "assets": [] }, "/": { "filePath": "/root/opencami/src/routes/index.tsx", "assets": [], "preloads": ["/assets/index-0gdwm1_H.js"] }, "/agents": { "filePath": "/root/opencami/src/routes/agents.tsx", "assets": [], "preloads": ["/assets/agents-BiTHBb6Z.js"] }, "/bots": { "filePath": "/root/opencami/src/routes/bots.tsx", "assets": [], "preloads": ["/assets/bots-DxhRnQp5.js"] }, "/connect": { "filePath": "/root/opencami/src/routes/connect.tsx", "assets": [], "preloads": ["/assets/connect-B48HecjN.js", "/assets/index-CGeJcqZ3.js", "/assets/button-BciDmec0.js", "/assets/react-DWx7OvUo.js"] }, "/dashboard": { "filePath": "/root/opencami/src/routes/dashboard.tsx", "assets": [], "preloads": ["/assets/dashboard-BVKx9FMy.js", "/assets/useQuery-D-sF8Tld.js"] }, "/files": { "filePath": "/root/opencami/src/routes/files.tsx", "assets": [], "preloads": ["/assets/files-SEycwYCa.js"] }, "/memory": { "filePath": "/root/opencami/src/routes/memory.tsx", "assets": [], "preloads": ["/assets/memory-C7lKdkmc.js"] }, "/new": { "filePath": "/root/opencami/src/routes/new.tsx", "assets": [], "preloads": ["/assets/new-DLlBm66g.js"] }, "/skills": { "filePath": "/root/opencami/src/routes/skills.tsx", "assets": [], "preloads": ["/assets/skills-D1T6uemU.js"] }, "/api/agents": { "filePath": "/root/opencami/src/routes/api/agents.ts" }, "/api/cron": { "filePath": "/root/opencami/src/routes/api/cron.ts" }, "/api/follow-ups": { "filePath": "/root/opencami/src/routes/api/follow-ups.ts" }, "/api/history": { "filePath": "/root/opencami/src/routes/api/history.ts" }, "/api/llm-features": { "filePath": "/root/opencami/src/routes/api/llm-features.ts" }, "/api/models": { "filePath": "/root/opencami/src/routes/api/models.ts" }, "/api/paths": { "filePath": "/root/opencami/src/routes/api/paths.ts" }, "/api/personas": { "filePath": "/root/opencami/src/routes/api/personas.ts" }, "/api/ping": { "filePath": "/root/opencami/src/routes/api/ping.ts" }, "/api/send": { "filePath": "/root/opencami/src/routes/api/send.ts" }, "/api/sessions": { "filePath": "/root/opencami/src/routes/api/sessions.ts" }, "/api/skills": { "filePath": "/root/opencami/src/routes/api/skills.ts" }, "/api/stream": { "filePath": "/root/opencami/src/routes/api/stream.ts" }, "/api/stt": { "filePath": "/root/opencami/src/routes/api/stt.ts" }, "/api/tts": { "filePath": "/root/opencami/src/routes/api/tts.ts" }, "/chat/$sessionKey": { "filePath": "/root/opencami/src/routes/chat/$sessionKey.tsx", "assets": [], "preloads": ["/assets/_sessionKey-Bg_9uype.js", "/assets/useQuery-D-sF8Tld.js", "/assets/tooltip-DOKkNFvu.js", "/assets/button-BciDmec0.js", "/assets/useMutation-BFl-7GnD.js", "/assets/use-file-explorer-state-BAa6Cxyr.js", "/assets/useBaseUiId-DFpBD0sg.js", "/assets/useControlled-CQHE0ITz.js", "/assets/useOnFirstRender-DlXHIIGk.js", "/assets/event-BCwqPPkP.js", "/assets/CSPContext-B3PAVjBL.js", "/assets/DirectionContext-CR5CCisG.js", "/assets/menu-CIwnliij.js", "/assets/opencami-logo-SVuYD55V.js", "/assets/proxy-BijR8W1L.js", "/assets/markdown-CdkuX06F.js", "/assets/index-CGeJcqZ3.js", "/assets/react-DWx7OvUo.js"] }, "/api/dashboard/crons": { "filePath": "/root/opencami/src/routes/api/dashboard/crons.ts" }, "/api/dashboard/gateway": { "filePath": "/root/opencami/src/routes/api/dashboard/gateway.ts" }, "/api/dashboard/system": { "filePath": "/root/opencami/src/routes/api/dashboard/system.ts" }, "/api/files/delete": { "filePath": "/root/opencami/src/routes/api/files/delete.ts" }, "/api/files/download": { "filePath": "/root/opencami/src/routes/api/files/download.ts" }, "/api/files/info": { "filePath": "/root/opencami/src/routes/api/files/info.ts" }, "/api/files/list": { "filePath": "/root/opencami/src/routes/api/files/list.ts" }, "/api/files/mkdir": { "filePath": "/root/opencami/src/routes/api/files/mkdir.ts" }, "/api/files/read": { "filePath": "/root/opencami/src/routes/api/files/read.ts" }, "/api/files/rename": { "filePath": "/root/opencami/src/routes/api/files/rename.ts" }, "/api/files/save": { "filePath": "/root/opencami/src/routes/api/files/save.ts" }, "/api/files/upload": { "filePath": "/root/opencami/src/routes/api/files/upload.ts" } }, "clientEntry": "/assets/main-B2CrcRuC.js" });
|
|
2
2
|
export {
|
|
3
3
|
tsrStartManifest
|
|
4
4
|
};
|
package/dist/server/assets/{follow-up-suggestions-BmSFSY87.js → follow-up-suggestions-C65ptDij.js}
RENAMED
|
@@ -2,7 +2,7 @@ import { jsxs, jsx } from "react/jsx-runtime";
|
|
|
2
2
|
import { useState, useRef, useEffect, memo } from "react";
|
|
3
3
|
import { HugeiconsIcon } from "@hugeicons/react";
|
|
4
4
|
import { Loading03Icon, ArrowRight01Icon } from "@hugeicons/core-free-icons";
|
|
5
|
-
import { a as useLlmSettingsStore, b as getLlmHeaders } from "./_sessionKey-
|
|
5
|
+
import { a as useLlmSettingsStore, b as getLlmHeaders } from "./_sessionKey-D8TGrDRM.js";
|
|
6
6
|
import { c as cn } from "./button-kI8fEIZQ.js";
|
|
7
7
|
import "@tanstack/react-router";
|
|
8
8
|
import "@tanstack/react-query";
|
|
@@ -26,7 +26,7 @@ import "remark-gfm";
|
|
|
26
26
|
import "./index-B_F4DTUu.js";
|
|
27
27
|
import "zustand/middleware";
|
|
28
28
|
import "react-dom";
|
|
29
|
-
import "./router-
|
|
29
|
+
import "./router-DaKDqc9w.js";
|
|
30
30
|
import "node:crypto";
|
|
31
31
|
import "node:fs";
|
|
32
32
|
import "node:os";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx } from "react/jsx-runtime";
|
|
2
2
|
import { useEffect } from "react";
|
|
3
|
-
import { R as Route } from "./router-
|
|
3
|
+
import { R as Route } from "./router-DaKDqc9w.js";
|
|
4
4
|
import "@tanstack/react-router";
|
|
5
5
|
import "@tanstack/react-query";
|
|
6
6
|
import "node:crypto";
|
|
@@ -12,7 +12,7 @@ import { execFile, execSync } from "node:child_process";
|
|
|
12
12
|
import { promisify } from "node:util";
|
|
13
13
|
import { readFile, mkdir, writeFile, rename, stat, readdir, rm, realpath, lstat } from "node:fs/promises";
|
|
14
14
|
import { posix } from "path";
|
|
15
|
-
const appCss = "/assets/styles-
|
|
15
|
+
const appCss = "/assets/styles-D0L88B64.css";
|
|
16
16
|
const swRegisterScript = `
|
|
17
17
|
(() => {
|
|
18
18
|
// Skip PWA service worker inside Capacitor native shell — they conflict
|
|
@@ -372,11 +372,11 @@ const $$splitComponentImporter$2 = () => import("./agents-BuE0Yum3.js");
|
|
|
372
372
|
const Route$t = createFileRoute("/agents")({
|
|
373
373
|
component: lazyRouteComponent($$splitComponentImporter$2, "component")
|
|
374
374
|
});
|
|
375
|
-
const $$splitComponentImporter$1 = () => import("./index-
|
|
375
|
+
const $$splitComponentImporter$1 = () => import("./index-gRco4Ina.js");
|
|
376
376
|
const Route$s = createFileRoute("/")({
|
|
377
377
|
component: lazyRouteComponent($$splitComponentImporter$1, "component")
|
|
378
378
|
});
|
|
379
|
-
const $$splitComponentImporter = () => import("./_sessionKey-
|
|
379
|
+
const $$splitComponentImporter = () => import("./_sessionKey-D8TGrDRM.js").then((n) => n.$);
|
|
380
380
|
const Route$r = createFileRoute("/chat/$sessionKey")({
|
|
381
381
|
component: lazyRouteComponent($$splitComponentImporter, "component")
|
|
382
382
|
});
|
|
@@ -529,7 +529,7 @@ function buildConnectParams(url, token, password, nonce) {
|
|
|
529
529
|
const clientId = "openclaw-control-ui";
|
|
530
530
|
const clientMode = "webchat";
|
|
531
531
|
const role = "operator";
|
|
532
|
-
const scopes = ["operator.admin", "operator.approvals", "operator.pairing"];
|
|
532
|
+
const scopes = ["operator.read", "operator.write", "operator.admin", "operator.approvals", "operator.pairing"];
|
|
533
533
|
if (!nonce) {
|
|
534
534
|
throw new Error(
|
|
535
535
|
"OpenClaw did not send connect.challenge nonce in time. If you are connecting cross-origin, ensure your origin is allowed (gateway.controlUi.allowedOrigins)."
|
|
@@ -593,8 +593,7 @@ class PersistentGatewayConnection {
|
|
|
593
593
|
connectPromise = null;
|
|
594
594
|
pendingRpcs = /* @__PURE__ */ new Map();
|
|
595
595
|
reconnectTimer = null;
|
|
596
|
-
|
|
597
|
-
maxReconnectDelay = 3e4;
|
|
596
|
+
reconnectAttempt = 0;
|
|
598
597
|
destroyed = false;
|
|
599
598
|
_devicePending = false;
|
|
600
599
|
_deviceId = "";
|
|
@@ -658,6 +657,7 @@ class PersistentGatewayConnection {
|
|
|
658
657
|
const timer = setTimeout(() => {
|
|
659
658
|
if (done) return;
|
|
660
659
|
done = true;
|
|
660
|
+
ws.off("message", onMessage);
|
|
661
661
|
resolve2("");
|
|
662
662
|
}, 3e3);
|
|
663
663
|
const onMessage = (data) => {
|
|
@@ -737,7 +737,7 @@ class PersistentGatewayConnection {
|
|
|
737
737
|
password: password || void 0
|
|
738
738
|
},
|
|
739
739
|
role: "operator",
|
|
740
|
-
scopes: ["operator.admin", "operator.approvals", "operator.pairing"],
|
|
740
|
+
scopes: ["operator.read", "operator.write", "operator.admin", "operator.approvals", "operator.pairing"],
|
|
741
741
|
userAgent: `opencami/${process.env.npm_package_version ?? "dev"} (node ${process.version})`,
|
|
742
742
|
locale: process.env.LANG || "en"
|
|
743
743
|
};
|
|
@@ -753,7 +753,7 @@ class PersistentGatewayConnection {
|
|
|
753
753
|
this._devicePending = false;
|
|
754
754
|
}
|
|
755
755
|
this.connected = true;
|
|
756
|
-
this.
|
|
756
|
+
this.reconnectAttempt = 0;
|
|
757
757
|
console.log("[gateway-ws] Persistent connection established");
|
|
758
758
|
}
|
|
759
759
|
_onMessage(data) {
|
|
@@ -777,7 +777,8 @@ class PersistentGatewayConnection {
|
|
|
777
777
|
const event = {
|
|
778
778
|
event: parsed.event,
|
|
779
779
|
payload: parsed.payload ?? {},
|
|
780
|
-
seq: parsed.seq
|
|
780
|
+
seq: parsed.seq,
|
|
781
|
+
stateVersion: typeof parsed.stateVersion === "number" ? parsed.stateVersion : void 0
|
|
781
782
|
};
|
|
782
783
|
const sessionKey = this._extractSessionKey(event);
|
|
783
784
|
for (const listener of this.globalListeners) {
|
|
@@ -787,15 +788,20 @@ class PersistentGatewayConnection {
|
|
|
787
788
|
}
|
|
788
789
|
}
|
|
789
790
|
if (sessionKey) {
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
791
|
+
let dispatched = false;
|
|
792
|
+
const eventSegments = sessionKey.split(":");
|
|
793
|
+
for (const [subKey, listeners] of this.sessionListeners) {
|
|
794
|
+
if (sessionKey === subKey || eventSegments.includes(subKey)) {
|
|
795
|
+
dispatched = true;
|
|
796
|
+
for (const listener of listeners) {
|
|
797
|
+
try {
|
|
798
|
+
listener(event);
|
|
799
|
+
} catch {
|
|
800
|
+
}
|
|
796
801
|
}
|
|
797
802
|
}
|
|
798
|
-
}
|
|
803
|
+
}
|
|
804
|
+
if (!dispatched) {
|
|
799
805
|
let buf = this.eventBuffer.get(sessionKey);
|
|
800
806
|
if (!buf) {
|
|
801
807
|
const timer = setTimeout(() => {
|
|
@@ -838,15 +844,18 @@ class PersistentGatewayConnection {
|
|
|
838
844
|
}
|
|
839
845
|
_scheduleReconnect() {
|
|
840
846
|
if (this.reconnectTimer) return;
|
|
841
|
-
const
|
|
842
|
-
|
|
843
|
-
|
|
847
|
+
const base = 1e3;
|
|
848
|
+
const cap = 3e4;
|
|
849
|
+
const exponential = Math.min(cap, base * 2 ** this.reconnectAttempt);
|
|
850
|
+
const delay = Math.round(Math.random() * exponential);
|
|
851
|
+
this.reconnectAttempt++;
|
|
852
|
+
console.log(`[gateway-ws] Reconnecting in ${delay}ms (attempt ${this.reconnectAttempt})...`);
|
|
844
853
|
this.reconnectTimer = setTimeout(async () => {
|
|
845
854
|
this.reconnectTimer = null;
|
|
846
855
|
try {
|
|
847
856
|
await this.ensureConnected();
|
|
848
857
|
} catch (err) {
|
|
849
|
-
console.error(
|
|
858
|
+
console.error(`[gateway-ws] Reconnect attempt ${this.reconnectAttempt} failed:`, err instanceof Error ? err.message : err);
|
|
850
859
|
}
|
|
851
860
|
}, delay);
|
|
852
861
|
}
|
|
@@ -876,14 +885,22 @@ class PersistentGatewayConnection {
|
|
|
876
885
|
this.sessionListeners.set(sessionKey, listeners);
|
|
877
886
|
}
|
|
878
887
|
listeners.add(listener);
|
|
879
|
-
const
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
888
|
+
const keysToFlush = [];
|
|
889
|
+
for (const bufKey of this.eventBuffer.keys()) {
|
|
890
|
+
if (bufKey === sessionKey || bufKey.split(":").includes(sessionKey)) {
|
|
891
|
+
keysToFlush.push(bufKey);
|
|
892
|
+
}
|
|
893
|
+
}
|
|
894
|
+
for (const bufKey of keysToFlush) {
|
|
895
|
+
const buf = this.eventBuffer.get(bufKey);
|
|
896
|
+
if (buf) {
|
|
897
|
+
this.eventBuffer.delete(bufKey);
|
|
898
|
+
clearTimeout(buf.timer);
|
|
899
|
+
for (const event of buf.events) {
|
|
900
|
+
try {
|
|
901
|
+
listener(event);
|
|
902
|
+
} catch {
|
|
903
|
+
}
|
|
887
904
|
}
|
|
888
905
|
}
|
|
889
906
|
}
|
|
@@ -923,235 +940,30 @@ function getPersistentConnection() {
|
|
|
923
940
|
}
|
|
924
941
|
return _proc.__opencamiGatewayInstance;
|
|
925
942
|
}
|
|
926
|
-
const sharedGatewayClients = /* @__PURE__ */ new Map();
|
|
927
|
-
function createGatewayClient() {
|
|
928
|
-
const pendingRpcs = /* @__PURE__ */ new Map();
|
|
929
|
-
const callbacks = /* @__PURE__ */ new Set();
|
|
930
|
-
let ws = null;
|
|
931
|
-
let closed = false;
|
|
932
|
-
let connected = false;
|
|
933
|
-
let connectPromise = null;
|
|
934
|
-
function rejectAll(err) {
|
|
935
|
-
for (const [, pending] of pendingRpcs) {
|
|
936
|
-
clearTimeout(pending.timer);
|
|
937
|
-
pending.reject(err);
|
|
938
|
-
}
|
|
939
|
-
pendingRpcs.clear();
|
|
940
|
-
}
|
|
941
|
-
function waitForRes(id, timeoutMs = 3e4) {
|
|
942
|
-
return new Promise((resolve2, reject) => {
|
|
943
|
-
const timer = setTimeout(() => {
|
|
944
|
-
pendingRpcs.delete(id);
|
|
945
|
-
reject(new Error(`RPC timeout waiting for ${id}`));
|
|
946
|
-
}, timeoutMs);
|
|
947
|
-
pendingRpcs.set(id, { resolve: resolve2, reject, timer });
|
|
948
|
-
});
|
|
949
|
-
}
|
|
950
|
-
function emitError(error) {
|
|
951
|
-
for (const callback of callbacks) {
|
|
952
|
-
try {
|
|
953
|
-
callback.onError?.(error);
|
|
954
|
-
} catch {
|
|
955
|
-
}
|
|
956
|
-
}
|
|
957
|
-
}
|
|
958
|
-
function emitEvent(event) {
|
|
959
|
-
for (const callback of callbacks) {
|
|
960
|
-
try {
|
|
961
|
-
callback.onEvent?.(event);
|
|
962
|
-
} catch {
|
|
963
|
-
}
|
|
964
|
-
}
|
|
965
|
-
}
|
|
966
|
-
function handleMessage(data) {
|
|
967
|
-
try {
|
|
968
|
-
const str = typeof data === "string" ? data : data.toString();
|
|
969
|
-
const parsed = JSON.parse(str);
|
|
970
|
-
if (parsed.type === "res") {
|
|
971
|
-
const pending = pendingRpcs.get(parsed.id);
|
|
972
|
-
if (!pending) return;
|
|
973
|
-
pendingRpcs.delete(parsed.id);
|
|
974
|
-
clearTimeout(pending.timer);
|
|
975
|
-
if (parsed.ok) pending.resolve(parsed.payload);
|
|
976
|
-
else pending.reject(new GatewayResponseError(parsed.error?.message ?? "gateway error", parsed.error?.code));
|
|
977
|
-
return;
|
|
978
|
-
}
|
|
979
|
-
if (parsed.type === "event") {
|
|
980
|
-
emitEvent({
|
|
981
|
-
event: parsed.event,
|
|
982
|
-
payload: parsed.payload ?? {},
|
|
983
|
-
seq: parsed.seq
|
|
984
|
-
});
|
|
985
|
-
}
|
|
986
|
-
} catch {
|
|
987
|
-
}
|
|
988
|
-
}
|
|
989
|
-
function handleClose() {
|
|
990
|
-
const wasConnected = connected;
|
|
991
|
-
connected = false;
|
|
992
|
-
ws = null;
|
|
993
|
-
rejectAll(new Error("Connection closed"));
|
|
994
|
-
if (!closed && wasConnected) {
|
|
995
|
-
emitError(new Error("Gateway client connection closed"));
|
|
996
|
-
}
|
|
997
|
-
}
|
|
998
|
-
async function connect() {
|
|
999
|
-
if (closed) throw new Error("Gateway client closed");
|
|
1000
|
-
if (connected && ws?.readyState === WebSocket.OPEN) return;
|
|
1001
|
-
if (connectPromise) return connectPromise;
|
|
1002
|
-
connectPromise = (async () => {
|
|
1003
|
-
const { url, token, password } = getGatewayConfig();
|
|
1004
|
-
const origin = process.env.OPENCAMI_ORIGIN?.trim();
|
|
1005
|
-
const nextWs = origin ? new WebSocket(url, { headers: { Origin: origin } }) : new WebSocket(url);
|
|
1006
|
-
ws = nextWs;
|
|
1007
|
-
await new Promise((resolve2, reject) => {
|
|
1008
|
-
const onOpen = () => {
|
|
1009
|
-
cleanup();
|
|
1010
|
-
resolve2();
|
|
1011
|
-
};
|
|
1012
|
-
const onError = (err) => {
|
|
1013
|
-
cleanup();
|
|
1014
|
-
reject(new Error(`WS open error: ${err.message}`));
|
|
1015
|
-
};
|
|
1016
|
-
const cleanup = () => {
|
|
1017
|
-
nextWs.off("open", onOpen);
|
|
1018
|
-
nextWs.off("error", onError);
|
|
1019
|
-
};
|
|
1020
|
-
nextWs.on("open", onOpen);
|
|
1021
|
-
nextWs.on("error", onError);
|
|
1022
|
-
});
|
|
1023
|
-
const nonce = await new Promise((resolve2) => {
|
|
1024
|
-
let done = false;
|
|
1025
|
-
const timer = setTimeout(() => {
|
|
1026
|
-
if (done) return;
|
|
1027
|
-
done = true;
|
|
1028
|
-
resolve2("");
|
|
1029
|
-
}, 3e3);
|
|
1030
|
-
const onMessage = (data) => {
|
|
1031
|
-
try {
|
|
1032
|
-
const str = typeof data === "string" ? data : data.toString();
|
|
1033
|
-
const parsed = JSON.parse(str);
|
|
1034
|
-
if (parsed.type === "event" && parsed.event === "connect.challenge") {
|
|
1035
|
-
const n = parsed.payload?.nonce;
|
|
1036
|
-
if (typeof n === "string" && n.length > 0) {
|
|
1037
|
-
clearTimeout(timer);
|
|
1038
|
-
nextWs.off("message", onMessage);
|
|
1039
|
-
if (done) return;
|
|
1040
|
-
done = true;
|
|
1041
|
-
resolve2(n);
|
|
1042
|
-
}
|
|
1043
|
-
}
|
|
1044
|
-
} catch {
|
|
1045
|
-
}
|
|
1046
|
-
};
|
|
1047
|
-
nextWs.on("message", onMessage);
|
|
1048
|
-
});
|
|
1049
|
-
nextWs.on("message", handleMessage);
|
|
1050
|
-
nextWs.on("close", handleClose);
|
|
1051
|
-
nextWs.on("error", (err) => {
|
|
1052
|
-
emitError(new Error(`Gateway client error: ${err.message}`));
|
|
1053
|
-
});
|
|
1054
|
-
const connectId = randomUUID();
|
|
1055
|
-
const connectParams = buildConnectParams(url, token, password, nonce);
|
|
1056
|
-
nextWs.send(JSON.stringify({
|
|
1057
|
-
type: "req",
|
|
1058
|
-
id: connectId,
|
|
1059
|
-
method: "connect",
|
|
1060
|
-
params: connectParams
|
|
1061
|
-
}));
|
|
1062
|
-
const hello = await waitForRes(connectId, 1e4);
|
|
1063
|
-
if (hello?.auth?.deviceToken) {
|
|
1064
|
-
const identity = loadOrCreateDeviceIdentity();
|
|
1065
|
-
storeDeviceToken(identity.deviceId, url, hello.auth.deviceToken);
|
|
1066
|
-
}
|
|
1067
|
-
connected = true;
|
|
1068
|
-
})();
|
|
1069
|
-
try {
|
|
1070
|
-
await connectPromise;
|
|
1071
|
-
} finally {
|
|
1072
|
-
connectPromise = null;
|
|
1073
|
-
}
|
|
1074
|
-
}
|
|
1075
|
-
async function sendReq(method, params) {
|
|
1076
|
-
await connect();
|
|
1077
|
-
if (!ws || ws.readyState !== WebSocket.OPEN) {
|
|
1078
|
-
throw new Error("Gateway client not connected");
|
|
1079
|
-
}
|
|
1080
|
-
const id = randomUUID();
|
|
1081
|
-
ws.send(JSON.stringify({ type: "req", id, method, params }));
|
|
1082
|
-
return await waitForRes(id);
|
|
1083
|
-
}
|
|
1084
|
-
function close() {
|
|
1085
|
-
if (closed) return;
|
|
1086
|
-
closed = true;
|
|
1087
|
-
connected = false;
|
|
1088
|
-
rejectAll(new Error("Gateway client closed"));
|
|
1089
|
-
const currentWs = ws;
|
|
1090
|
-
ws = null;
|
|
1091
|
-
if (currentWs) {
|
|
1092
|
-
currentWs.off("message", handleMessage);
|
|
1093
|
-
currentWs.off("close", handleClose);
|
|
1094
|
-
currentWs.close();
|
|
1095
|
-
}
|
|
1096
|
-
callbacks.clear();
|
|
1097
|
-
}
|
|
1098
|
-
function isClosed() {
|
|
1099
|
-
return closed;
|
|
1100
|
-
}
|
|
1101
|
-
function addCallbacks(callbacksToAdd) {
|
|
1102
|
-
if (!callbacksToAdd?.onEvent && !callbacksToAdd?.onError) {
|
|
1103
|
-
return () => {
|
|
1104
|
-
};
|
|
1105
|
-
}
|
|
1106
|
-
callbacks.add(callbacksToAdd);
|
|
1107
|
-
return () => {
|
|
1108
|
-
callbacks.delete(callbacksToAdd);
|
|
1109
|
-
};
|
|
1110
|
-
}
|
|
1111
|
-
return { connect, sendReq, close, isClosed, addCallbacks };
|
|
1112
|
-
}
|
|
1113
|
-
function releaseGatewayClient(key) {
|
|
1114
|
-
const entry = sharedGatewayClients.get(key);
|
|
1115
|
-
if (!entry) return;
|
|
1116
|
-
entry.refs -= 1;
|
|
1117
|
-
if (entry.refs > 0) return;
|
|
1118
|
-
entry.client.close();
|
|
1119
|
-
sharedGatewayClients.delete(key);
|
|
1120
|
-
}
|
|
1121
943
|
async function acquireGatewayClient(key, callbacks) {
|
|
1122
|
-
const
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
client: existing.client,
|
|
1128
|
-
release: () => {
|
|
1129
|
-
removeCallbacks2();
|
|
1130
|
-
releaseGatewayClient(key);
|
|
1131
|
-
}
|
|
1132
|
-
};
|
|
944
|
+
const conn = getPersistentConnection();
|
|
945
|
+
await conn.ensureConnected();
|
|
946
|
+
let unsubscribe = null;
|
|
947
|
+
if (callbacks?.onEvent) {
|
|
948
|
+
unsubscribe = conn.subscribe(key, callbacks.onEvent);
|
|
1133
949
|
}
|
|
1134
|
-
const client = createGatewayClient();
|
|
1135
|
-
const removeCallbacks = client.addCallbacks(callbacks);
|
|
1136
|
-
await client.connect();
|
|
1137
|
-
sharedGatewayClients.set(key, { refs: 1, client });
|
|
1138
950
|
return {
|
|
1139
|
-
client
|
|
951
|
+
client: {
|
|
952
|
+
connect: () => conn.ensureConnected(),
|
|
953
|
+
sendReq: (method, params) => conn.rpc(method, params),
|
|
954
|
+
close: () => {
|
|
955
|
+
},
|
|
956
|
+
isClosed: () => !conn.isConnected,
|
|
957
|
+
addCallbacks: () => () => {
|
|
958
|
+
}
|
|
959
|
+
},
|
|
1140
960
|
release: () => {
|
|
1141
|
-
|
|
1142
|
-
releaseGatewayClient(key);
|
|
961
|
+
unsubscribe?.();
|
|
1143
962
|
}
|
|
1144
963
|
};
|
|
1145
964
|
}
|
|
1146
|
-
async function gatewayRpcShared(method, params,
|
|
1147
|
-
|
|
1148
|
-
return gatewayRpc(method, params);
|
|
1149
|
-
}
|
|
1150
|
-
const existing = sharedGatewayClients.get(key);
|
|
1151
|
-
if (!existing || existing.client.isClosed()) {
|
|
1152
|
-
return gatewayRpc(method, params);
|
|
1153
|
-
}
|
|
1154
|
-
return existing.client.sendReq(method, params);
|
|
965
|
+
async function gatewayRpcShared(method, params, _key) {
|
|
966
|
+
return gatewayRpc(method, params);
|
|
1155
967
|
}
|
|
1156
968
|
async function gatewayRpc(method, params) {
|
|
1157
969
|
const conn = getPersistentConnection();
|
|
@@ -1528,6 +1340,8 @@ const Route$o = createFileRoute("/api/stream")({
|
|
|
1528
1340
|
let closed = false;
|
|
1529
1341
|
let heartbeat = null;
|
|
1530
1342
|
let releaseClient = null;
|
|
1343
|
+
let lastSeq = -1;
|
|
1344
|
+
let lastEventFingerprint = "";
|
|
1531
1345
|
function writeChunk(chunk) {
|
|
1532
1346
|
if (closed) return;
|
|
1533
1347
|
try {
|
|
@@ -1564,9 +1378,16 @@ const Route$o = createFileRoute("/api/stream")({
|
|
|
1564
1378
|
try {
|
|
1565
1379
|
const handle = await acquireGatewayClient(key, {
|
|
1566
1380
|
onEvent(event) {
|
|
1381
|
+
if (typeof event.seq === "number") {
|
|
1382
|
+
if (event.seq <= lastSeq) return;
|
|
1383
|
+
lastSeq = event.seq;
|
|
1384
|
+
}
|
|
1385
|
+
const fp = event.event + ":" + JSON.stringify(event.payload);
|
|
1386
|
+
if (fp === lastEventFingerprint) return;
|
|
1387
|
+
lastEventFingerprint = fp;
|
|
1567
1388
|
const p = event.payload;
|
|
1568
1389
|
const eventSessionKey = typeof p?.sessionKey === "string" ? p.sessionKey : "";
|
|
1569
|
-
if (eventSessionKey && !eventSessionKey.includes(key)) {
|
|
1390
|
+
if (eventSessionKey && eventSessionKey !== key && !eventSessionKey.split(":").includes(key)) {
|
|
1570
1391
|
return;
|
|
1571
1392
|
}
|
|
1572
1393
|
send({
|
|
@@ -5,7 +5,7 @@ import { HugeiconsIcon } from "@hugeicons/react";
|
|
|
5
5
|
import { Search01Icon, Cancel01Icon, Loading03Icon } from "@hugeicons/core-free-icons";
|
|
6
6
|
import { D as DialogRoot, a as DialogContent } from "./use-file-explorer-state-E6cUvMva.js";
|
|
7
7
|
import { useQueryClient } from "@tanstack/react-query";
|
|
8
|
-
import { c as chatQueryKeys } from "./_sessionKey-
|
|
8
|
+
import { c as chatQueryKeys } from "./_sessionKey-D8TGrDRM.js";
|
|
9
9
|
import { c as cn } from "./button-kI8fEIZQ.js";
|
|
10
10
|
import "@base-ui/react/dialog";
|
|
11
11
|
import "zustand";
|
|
@@ -26,7 +26,7 @@ import "remark-gfm";
|
|
|
26
26
|
import "./index-B_F4DTUu.js";
|
|
27
27
|
import "zustand/middleware";
|
|
28
28
|
import "react-dom";
|
|
29
|
-
import "./router-
|
|
29
|
+
import "./router-DaKDqc9w.js";
|
|
30
30
|
import "node:crypto";
|
|
31
31
|
import "node:fs";
|
|
32
32
|
import "node:os";
|
|
@@ -8,7 +8,7 @@ import { D as DialogRoot, a as DialogContent, b as DialogTitle, c as DialogDescr
|
|
|
8
8
|
import { S as Switch } from "./switch-BZzwkgAQ.js";
|
|
9
9
|
import { T as Tabs, a as TabsList, b as TabsTab } from "./tabs-CWbp3mT4.js";
|
|
10
10
|
import { u as useChatSettings } from "./index-B_F4DTUu.js";
|
|
11
|
-
import { u as useLlmSettings, g as getLlmProviderDefaults } from "./_sessionKey-
|
|
11
|
+
import { u as useLlmSettings, g as getLlmProviderDefaults } from "./_sessionKey-D8TGrDRM.js";
|
|
12
12
|
import "@base-ui/react/merge-props";
|
|
13
13
|
import "@base-ui/react/use-render";
|
|
14
14
|
import "class-variance-authority";
|
|
@@ -35,7 +35,7 @@ import "react-markdown";
|
|
|
35
35
|
import "remark-breaks";
|
|
36
36
|
import "remark-gfm";
|
|
37
37
|
import "react-dom";
|
|
38
|
-
import "./router-
|
|
38
|
+
import "./router-DaKDqc9w.js";
|
|
39
39
|
import "node:crypto";
|
|
40
40
|
import "node:fs";
|
|
41
41
|
import "node:os";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useState, useEffect } from "react";
|
|
3
|
-
import { C as Collapsible, d as CollapsibleTrigger, e as CollapsiblePanel } from "./_sessionKey-
|
|
3
|
+
import { C as Collapsible, d as CollapsibleTrigger, e as CollapsiblePanel } from "./_sessionKey-D8TGrDRM.js";
|
|
4
4
|
import { HugeiconsIcon } from "@hugeicons/react";
|
|
5
5
|
import { ArrowDown01Icon } from "@hugeicons/core-free-icons";
|
|
6
6
|
import { B as Button } from "./button-kI8fEIZQ.js";
|
|
@@ -26,7 +26,7 @@ import "remark-gfm";
|
|
|
26
26
|
import "./index-B_F4DTUu.js";
|
|
27
27
|
import "zustand/middleware";
|
|
28
28
|
import "react-dom";
|
|
29
|
-
import "./router-
|
|
29
|
+
import "./router-DaKDqc9w.js";
|
|
30
30
|
import "node:crypto";
|
|
31
31
|
import "node:fs";
|
|
32
32
|
import "node:os";
|
package/dist/server/server.js
CHANGED
|
@@ -184,7 +184,7 @@ function getResponse() {
|
|
|
184
184
|
return event.res;
|
|
185
185
|
}
|
|
186
186
|
async function getStartManifest(matchedRoutes) {
|
|
187
|
-
const { tsrStartManifest } = await import("./assets/_tanstack-start-manifest_v-
|
|
187
|
+
const { tsrStartManifest } = await import("./assets/_tanstack-start-manifest_v-DalBo2bY.js");
|
|
188
188
|
const startManifest = tsrStartManifest();
|
|
189
189
|
const rootRoute = startManifest.routes[rootRouteId] = startManifest.routes[rootRouteId] || {};
|
|
190
190
|
rootRoute.assets = rootRoute.assets || [];
|
|
@@ -753,7 +753,7 @@ let entriesPromise;
|
|
|
753
753
|
let baseManifestPromise;
|
|
754
754
|
let cachedFinalManifestPromise;
|
|
755
755
|
async function loadEntries() {
|
|
756
|
-
const routerEntry = await import("./assets/router-
|
|
756
|
+
const routerEntry = await import("./assets/router-DaKDqc9w.js").then((n) => n.r);
|
|
757
757
|
const startEntry = await import("./assets/start-HYkvq4Ni.js");
|
|
758
758
|
return { startEntry, routerEntry };
|
|
759
759
|
}
|