local-operator-ui 0.4.0 → 0.4.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/README.md
CHANGED
|
@@ -13,7 +13,9 @@
|
|
|
13
13
|
|
|
14
14
|
<br />
|
|
15
15
|
|
|
16
|
-
<
|
|
16
|
+
<div style="display: flex; justify-content: center; border-radius: 8px; overflow: hidden;">
|
|
17
|
+
<img src="./resources/preview-example.gif" alt="Local Operator UI Dashboard Example" style="width: 100%; max-width: 800px;">
|
|
18
|
+
</div>
|
|
17
19
|
|
|
18
20
|
<br />
|
|
19
21
|
|
package/out/main/index.jsc
CHANGED
|
Binary file
|
package/out/preload/index.jsc
CHANGED
|
Binary file
|
|
@@ -29848,12 +29848,10 @@ class WebSocketClient extends EventEmitter {
|
|
|
29848
29848
|
const error = new Error(
|
|
29849
29849
|
`WebSocket connection failed after ${this.options.maxReconnectAttempts} attempts. In cooldown period.`
|
|
29850
29850
|
);
|
|
29851
|
-
console.error(error.message);
|
|
29852
29851
|
return Promise.reject(error);
|
|
29853
29852
|
}
|
|
29854
29853
|
if (this.isReconnecting) {
|
|
29855
29854
|
const error = new Error("WebSocket reconnection already in progress");
|
|
29856
|
-
console.error(error.message);
|
|
29857
29855
|
return Promise.reject(error);
|
|
29858
29856
|
}
|
|
29859
29857
|
const now = Date.now();
|
|
@@ -30202,11 +30200,7 @@ class WebSocketClient extends EventEmitter {
|
|
|
30202
30200
|
if (this.status === "disconnected" || this.status === "reconnecting") {
|
|
30203
30201
|
this.reconnectAttempts++;
|
|
30204
30202
|
this.reconnectTimeoutId = null;
|
|
30205
|
-
this.connect().catch((
|
|
30206
|
-
console.error(
|
|
30207
|
-
`Reconnection attempt ${this.reconnectAttempts} failed for ${this.messageId}:`,
|
|
30208
|
-
error
|
|
30209
|
-
);
|
|
30203
|
+
this.connect().catch(() => {
|
|
30210
30204
|
if (this.reconnectAttempts >= (this.options.maxReconnectAttempts || 0)) {
|
|
30211
30205
|
this.enterCooldown();
|
|
30212
30206
|
} else if (this.status !== "failed") {
|
|
@@ -35040,13 +35034,21 @@ const useScrollToBottom = (dependencies = [], threshold = 100, buttonThreshold =
|
|
|
35040
35034
|
while (parent) {
|
|
35041
35035
|
const { overflow, overflowY } = window.getComputedStyle(parent);
|
|
35042
35036
|
if (overflow === "auto" || overflow === "scroll" || overflowY === "auto" || overflowY === "scroll") {
|
|
35043
|
-
containerRef.current
|
|
35044
|
-
|
|
35037
|
+
if (containerRef.current !== parent) {
|
|
35038
|
+
containerRef.current = parent;
|
|
35039
|
+
checkScrollPosition();
|
|
35040
|
+
parent.addEventListener("scroll", handleScroll, { passive: true });
|
|
35041
|
+
}
|
|
35045
35042
|
break;
|
|
35046
35043
|
}
|
|
35047
35044
|
parent = parent.parentElement;
|
|
35048
35045
|
}
|
|
35049
|
-
|
|
35046
|
+
return () => {
|
|
35047
|
+
if (containerRef.current) {
|
|
35048
|
+
containerRef.current.removeEventListener("scroll", handleScroll);
|
|
35049
|
+
}
|
|
35050
|
+
};
|
|
35051
|
+
}, [checkScrollPosition, handleScroll]);
|
|
35050
35052
|
return {
|
|
35051
35053
|
ref,
|
|
35052
35054
|
containerRef,
|
|
@@ -46908,29 +46910,33 @@ const ModelSelect = ({
|
|
|
46908
46910
|
getOptionLabel: (option) => option.name,
|
|
46909
46911
|
isOptionEqualToValue: (option, value2) => option.id === value2.id,
|
|
46910
46912
|
groupBy: (option) => getProviderFromId(option.id),
|
|
46911
|
-
renderOption: (props, option) =>
|
|
46912
|
-
|
|
46913
|
-
|
|
46914
|
-
|
|
46915
|
-
|
|
46916
|
-
|
|
46917
|
-
|
|
46918
|
-
|
|
46919
|
-
|
|
46920
|
-
|
|
46921
|
-
|
|
46922
|
-
|
|
46923
|
-
|
|
46924
|
-
|
|
46925
|
-
|
|
46926
|
-
|
|
46927
|
-
|
|
46928
|
-
|
|
46929
|
-
|
|
46930
|
-
|
|
46931
|
-
|
|
46932
|
-
|
|
46933
|
-
|
|
46913
|
+
renderOption: (props, option) => {
|
|
46914
|
+
const { key, ...rest } = props;
|
|
46915
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("li", { ...rest, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(OptionContainer, { children: [
|
|
46916
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(OptionLabelContainer, { children: [
|
|
46917
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(OptionLabel, { children: option.name }),
|
|
46918
|
+
option.recommended && // @ts-ignore
|
|
46919
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Tooltip, { title: "Recommended based on community usage and feedback", children: /* @__PURE__ */ jsxRuntimeExports.jsx(RecommendedStar, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(FontAwesomeIcon, { icon: faStar, size: "xs" }) }) })
|
|
46920
|
+
] }),
|
|
46921
|
+
option.description && /* @__PURE__ */ jsxRuntimeExports.jsx(OptionDescription, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
46922
|
+
Markdown,
|
|
46923
|
+
{
|
|
46924
|
+
components: {
|
|
46925
|
+
a: ({ href, children }) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
46926
|
+
"a",
|
|
46927
|
+
{
|
|
46928
|
+
href,
|
|
46929
|
+
target: "_blank",
|
|
46930
|
+
rel: "noopener noreferrer",
|
|
46931
|
+
children
|
|
46932
|
+
}
|
|
46933
|
+
)
|
|
46934
|
+
},
|
|
46935
|
+
children: option.description
|
|
46936
|
+
}
|
|
46937
|
+
) })
|
|
46938
|
+
] }) }, key);
|
|
46939
|
+
},
|
|
46934
46940
|
freeSolo: allowCustom,
|
|
46935
46941
|
renderInput: (params) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
46936
46942
|
TextField,
|
|
@@ -107462,12 +107468,11 @@ const useWebSocketMessage = (options) => {
|
|
|
107462
107468
|
reactExports.useEffect(() => {
|
|
107463
107469
|
if (autoConnect && messageId && baseUrl && connectRef.current && !clientRef.current && !globalClientsRef.current[messageId]) {
|
|
107464
107470
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().substring(11, 23);
|
|
107465
|
-
console.log(`[${timestamp}] Auto-connecting WebSocket for ${messageId}`);
|
|
107466
107471
|
globalClientsRef.current[messageId] = true;
|
|
107467
107472
|
setTimeout(() => {
|
|
107468
107473
|
if (connectRef.current) {
|
|
107469
107474
|
connectRef.current().catch((err) => {
|
|
107470
|
-
console.
|
|
107475
|
+
console.warn(
|
|
107471
107476
|
`[${timestamp}] Error auto-connecting WebSocket for ${messageId}:`,
|
|
107472
107477
|
err
|
|
107473
107478
|
);
|
|
@@ -110376,6 +110381,7 @@ const ChatPage = () => {
|
|
|
110376
110381
|
},
|
|
110377
110382
|
[addMessage, conversationId, setCurrentJobId, setIsLoading]
|
|
110378
110383
|
);
|
|
110384
|
+
const { data: configData } = useConfig();
|
|
110379
110385
|
const handleSendMessage = reactExports.useCallback(
|
|
110380
110386
|
async (content2, attachments) => {
|
|
110381
110387
|
if (!conversationId) return;
|
|
@@ -110404,16 +110410,15 @@ const ChatPage = () => {
|
|
|
110404
110410
|
([_2, value]) => value !== void 0 && value !== null
|
|
110405
110411
|
)
|
|
110406
110412
|
);
|
|
110413
|
+
const resolvedHosting = !agentData?.hosting || agentData.hosting === "default" || agentData.hosting.trim() === "" ? configData?.values.hosting || "" : agentData.hosting;
|
|
110414
|
+
const resolvedModel = !agentData?.model || agentData.model === "default" || agentData.model.trim() === "" ? configData?.values.model_name || "" : agentData.model;
|
|
110407
110415
|
const jobDetails = await apiClient.chat.processAgentChatAsync(
|
|
110408
110416
|
conversationId,
|
|
110409
110417
|
{
|
|
110410
|
-
hosting:
|
|
110411
|
-
|
|
110412
|
-
model: agentData?.model || "google/gemini-2.0-flash-001",
|
|
110413
|
-
// Use agent's model or default
|
|
110418
|
+
hosting: resolvedHosting,
|
|
110419
|
+
model: resolvedModel,
|
|
110414
110420
|
prompt: content2,
|
|
110415
110421
|
persist_conversation: true,
|
|
110416
|
-
// Persist conversation history
|
|
110417
110422
|
user_message_id: userMessage.id,
|
|
110418
110423
|
options: Object.keys(filteredOptions).length > 0 ? filteredOptions : void 0,
|
|
110419
110424
|
attachments: attachments.length > 0 ? attachments : void 0
|
|
@@ -110452,7 +110457,8 @@ ${error2.stack || ""}`;
|
|
|
110452
110457
|
setIsLoading,
|
|
110453
110458
|
agentData,
|
|
110454
110459
|
apiClient,
|
|
110455
|
-
setCurrentJobId
|
|
110460
|
+
setCurrentJobId,
|
|
110461
|
+
configData
|
|
110456
110462
|
]
|
|
110457
110463
|
);
|
|
110458
110464
|
const rawInfoContent = reactExports.useMemo(() => {
|
package/out/renderer/index.html
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
<!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
|
|
9
9
|
<meta http-equiv="Content-Security-Policy"
|
|
10
10
|
content="default-src 'self'; connect-src 'self' http://localhost:1111 http://127.0.0.1:1111 ws://localhost:1111 ws://127.0.0.1:1111; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: http://localhost:1111 http://127.0.0.1:1111; media-src 'self' http://localhost:1111 http://127.0.0.1:1111; font-src 'self'" />
|
|
11
|
-
<script type="module" crossorigin src="./assets/index-
|
|
11
|
+
<script type="module" crossorigin src="./assets/index-DHvoVezG.js"></script>
|
|
12
12
|
<link rel="modulepreload" crossorigin href="./assets/error-boundary-HK_94N6W.js">
|
|
13
13
|
<link rel="stylesheet" crossorigin href="./assets/error-boundary-B9KBGB-g.css">
|
|
14
14
|
<link rel="stylesheet" crossorigin href="./assets/index-94BTFuhu.css">
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "local-operator-ui",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.2",
|
|
4
4
|
"productName": "Local Operator",
|
|
5
5
|
"description": "User interface for AI agent assistants that run Python code safely on your device through an intuitive chat interface. Supports local and cloud LLM models with built-in security features.",
|
|
6
6
|
"main": "./out/main/index.js",
|
|
@@ -167,8 +167,18 @@
|
|
|
167
167
|
"gatekeeperAssess": false,
|
|
168
168
|
"entitlements": "build/entitlements.mac.plist",
|
|
169
169
|
"entitlementsInherit": "build/entitlements.mac.plist",
|
|
170
|
-
"target": [
|
|
171
|
-
|
|
170
|
+
"target": [
|
|
171
|
+
{
|
|
172
|
+
"target": "dmg",
|
|
173
|
+
"arch": ["universal"]
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
"target": "zip",
|
|
177
|
+
"arch": ["universal"]
|
|
178
|
+
}
|
|
179
|
+
],
|
|
180
|
+
"artifactName": "${name}-${version}-${arch}.${ext}",
|
|
181
|
+
"x64ArchFiles": "Contents/Resources/python/**/*"
|
|
172
182
|
},
|
|
173
183
|
"dmg": {
|
|
174
184
|
"sign": false,
|