machinaos 0.0.77 → 0.0.78

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.
Files changed (44) hide show
  1. package/README.md +5 -5
  2. package/client/dist/assets/ActionBar-Du2MSFSz.js +1 -0
  3. package/client/dist/assets/ApiKeyInput-k2LBmBjb.js +1 -0
  4. package/client/dist/assets/ApiKeyPanel-C_bV9U0X.js +1 -0
  5. package/client/dist/assets/ApiUsageSection-CmVfwZzL.js +1 -0
  6. package/client/dist/assets/EmailPanel-CeKIMGu-.js +1 -0
  7. package/client/dist/assets/OAuthPanel-KA3t3Q2K.js +1 -0
  8. package/client/dist/assets/QrPairingPanel-NgNpJNuk.js +1 -0
  9. package/client/dist/assets/RateLimitSection-Du5YNVIA.js +1 -0
  10. package/client/dist/assets/{StatusCard-BlufvZD-.js → StatusCard-DNLyayXc.js} +1 -1
  11. package/client/dist/assets/index-DQ0nwhec.js +257 -0
  12. package/client/dist/assets/{index-bhvWG-f4.css → index-DxmbVskS.css} +1 -1
  13. package/client/dist/assets/vendor-flow-CZmBvHRo.js +1 -0
  14. package/client/dist/assets/vendor-icons-CVrPjN2Q.js +22 -0
  15. package/client/dist/assets/vendor-markdown-CRou3yQ5.js +62 -0
  16. package/client/dist/assets/vendor-misc-C4VxKHs5.js +1 -0
  17. package/client/dist/assets/vendor-query-SzWcOU0G.js +1 -0
  18. package/client/dist/assets/vendor-radix-Dnos29jG.js +56 -0
  19. package/client/dist/assets/vendor-react-DvWIbVx0.js +1 -0
  20. package/client/dist/index.html +9 -9
  21. package/client/package.json +40 -40
  22. package/install.ps1 +1 -1
  23. package/install.sh +1 -1
  24. package/package.json +4 -4
  25. package/server/nodejs/package.json +5 -5
  26. package/server/nodejs/src/index.ts +22 -5
  27. package/server/nodes/android/_router.py +20 -1
  28. package/server/pyproject.toml +13 -12
  29. package/client/dist/assets/ActionBar-DAHXJmEU.js +0 -1
  30. package/client/dist/assets/ApiKeyInput-DljozMIZ.js +0 -1
  31. package/client/dist/assets/ApiKeyPanel-BLCwKv-F.js +0 -1
  32. package/client/dist/assets/ApiUsageSection-FWVtg8Sd.js +0 -1
  33. package/client/dist/assets/EmailPanel-Cb1y_sxm.js +0 -1
  34. package/client/dist/assets/OAuthPanel-BUvQtzRH.js +0 -1
  35. package/client/dist/assets/QrPairingPanel-DgHdW1GW.js +0 -1
  36. package/client/dist/assets/RateLimitSection-B2lBVQs0.js +0 -1
  37. package/client/dist/assets/index-DNx1tG6T.js +0 -232
  38. package/client/dist/assets/vendor-flow-apeQB2hf.js +0 -1
  39. package/client/dist/assets/vendor-icons-BPyNc2rK.js +0 -22
  40. package/client/dist/assets/vendor-markdown-Bx_GU1E7.js +0 -62
  41. package/client/dist/assets/vendor-misc-4my8ai2A.js +0 -1
  42. package/client/dist/assets/vendor-query-to9T1kjL.js +0 -1
  43. package/client/dist/assets/vendor-radix-BGeDhy8U.js +0 -56
  44. package/client/dist/assets/vendor-react-CxXU_nq3.js +0 -1
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "react-flow-client",
3
3
  "private": true,
4
- "version": "0.0.77",
4
+ "version": "0.0.78",
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "start": "vite --host 0.0.0.0",
@@ -17,60 +17,60 @@
17
17
  "test:nodepanels": "vitest run src/hooks/__tests__/useDragVariable.test.ts src/hooks/__tests__/useParameterPanel.test.ts src/components/parameterPanel/__tests__ src/components/__tests__/OutputPanel.test.tsx"
18
18
  },
19
19
  "dependencies": {
20
- "@eslint/js": "^9.33.0",
20
+ "@eslint/js": "^9.39.4",
21
21
  "@fontsource-variable/geist": "^5.2.8",
22
22
  "@hookform/resolvers": "^5.2.2",
23
- "@lobehub/icons": "^2.45.0",
23
+ "@lobehub/icons": "^2.48.0",
24
24
  "@lukemorales/query-key-factory": "^1.3.4",
25
25
  "@radix-ui/react-collapsible": "^1.1.12",
26
26
  "@radix-ui/react-dialog": "^1.1.15",
27
27
  "@radix-ui/react-slot": "^1.2.4",
28
28
  "@tailwindcss/typography": "^0.5.19",
29
- "@tanstack/query-sync-storage-persister": "^5.100.2",
30
- "@tanstack/react-query": "^5.100.2",
31
- "@tanstack/react-query-persist-client": "^5.100.2",
32
- "@types/google.maps": "^3.58.1",
33
- "@types/node": "^24.3.1",
34
- "@types/prismjs": "^1.26.5",
35
- "@types/react": "^19.1.10",
36
- "@types/react-dom": "^19.1.7",
29
+ "@tanstack/query-sync-storage-persister": "^5.100.10",
30
+ "@tanstack/react-query": "^5.100.10",
31
+ "@tanstack/react-query-persist-client": "^5.100.10",
32
+ "@types/google.maps": "^3.64.0",
33
+ "@types/node": "^24.12.3",
34
+ "@types/prismjs": "^1.26.6",
35
+ "@types/react": "^19.2.14",
36
+ "@types/react-dom": "^19.2.3",
37
37
  "@uiw/react-json-view": "2.0.0-alpha.41",
38
- "@vitejs/plugin-react": "^5.0.0",
39
- "autoprefixer": "^10.4.21",
38
+ "@vitejs/plugin-react": "^5.2.0",
39
+ "autoprefixer": "^10.5.0",
40
40
  "class-variance-authority": "^0.7.1",
41
41
  "clsx": "^2.1.1",
42
- "cmdk": "^1",
43
- "eslint": "^9.33.0",
44
- "eslint-plugin-react-hooks": "^7.0.1",
45
- "eslint-plugin-react-refresh": "^0.4.20",
46
- "fuzzysort": "^3",
47
- "globals": "^16.3.0",
48
- "idb-keyval": "^6",
49
- "lucide-react": "^1.8.0",
42
+ "cmdk": "^1.1.1",
43
+ "eslint": "^9.39.4",
44
+ "eslint-plugin-react-hooks": "^7.1.1",
45
+ "eslint-plugin-react-refresh": "^0.4.26",
46
+ "fuzzysort": "^3.1.0",
47
+ "globals": "^16.5.0",
48
+ "idb-keyval": "^6.2.2",
49
+ "lucide-react": "^1.14.0",
50
50
  "next-themes": "^0.4.6",
51
51
  "partysocket": "1.1.18",
52
- "postcss": "^8.5.6",
52
+ "postcss": "^8.5.14",
53
53
  "prismjs": "^1.30.0",
54
54
  "qrcode.react": "^4.2.0",
55
55
  "radix-ui": "^1.4.3",
56
- "react": "^19.1.1",
57
- "react-dom": "^19.1.1",
58
- "react-hook-form": "^7.72.1",
56
+ "react": "^19.2.6",
57
+ "react-dom": "^19.2.6",
58
+ "react-hook-form": "^7.75.0",
59
59
  "react-markdown": "^10.1.0",
60
60
  "react-simple-code-editor": "^0.14.1",
61
- "react-virtuoso": "^4",
61
+ "react-virtuoso": "^4.18.7",
62
62
  "reactflow": "^11.11.4",
63
63
  "remark-breaks": "^4.0.0",
64
64
  "remark-gfm": "^4.0.1",
65
- "shadcn": "^4.2.0",
65
+ "shadcn": "^4.7.0",
66
66
  "sonner": "^2.0.7",
67
- "tailwind-merge": "^3.5.0",
68
- "tailwindcss": "^4.1.13",
67
+ "tailwind-merge": "^3.6.0",
68
+ "tailwindcss": "^4.3.0",
69
69
  "tw-animate-css": "^1.4.0",
70
- "typescript": "^5.9.2",
71
- "vite": "^7.1.2",
72
- "zod": "^4.3.6",
73
- "zustand": "^5.0.8"
70
+ "typescript": "^5.9.3",
71
+ "vite": "^7.3.3",
72
+ "zod": "^4.4.3",
73
+ "zustand": "^5.0.13"
74
74
  },
75
75
  "overrides": {
76
76
  "@emoji-mart/react": {
@@ -82,18 +82,18 @@
82
82
  }
83
83
  },
84
84
  "devDependencies": {
85
- "@tailwindcss/vite": "^4.2.2",
86
- "@tanstack/react-query-devtools": "^5.100.2",
85
+ "@tailwindcss/vite": "^4.3.0",
86
+ "@tanstack/react-query-devtools": "^5.100.10",
87
87
  "@testing-library/jest-dom": "^6.9.1",
88
88
  "@testing-library/react": "^16.3.2",
89
- "@testing-library/user-event": "^14.5.2",
89
+ "@testing-library/user-event": "^14.6.1",
90
+ "@typescript-eslint/parser": "^8.59.2",
90
91
  "@typescript/native-preview": "7.0.0-dev.20260504.1",
91
- "@typescript-eslint/parser": "^8.54.0",
92
- "@vitest/coverage-v8": "^2.1.9",
92
+ "@vitest/coverage-v8": "^3.0.0",
93
93
  "babel-plugin-react-compiler": "19.1.0-rc.3",
94
94
  "jsdom": "^25.0.1",
95
95
  "rollup-plugin-visualizer": "^7.0.1",
96
- "typescript-eslint": "^8.54.0",
97
- "vitest": "^2.1.9"
96
+ "typescript-eslint": "^8.59.2",
97
+ "vitest": "^3.0.0"
98
98
  }
99
99
  }
package/install.ps1 CHANGED
@@ -1,5 +1,5 @@
1
1
  # MachinaOS Installer for Windows
2
- # Usage: iwr -useb https://raw.githubusercontent.com/trohitg/MachinaOS/main/install.ps1 | iex
2
+ # Usage: iwr -useb https://raw.githubusercontent.com/zeenie-ai/MachinaOS/main/install.ps1 | iex
3
3
  #
4
4
  # This script installs MachinaOS and its dependencies:
5
5
  # - Node.js 22+ (via winget/choco)
package/install.sh CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env bash
2
2
  # MachinaOS Installer
3
- # Usage: curl -fsSL https://raw.githubusercontent.com/trohitg/MachinaOS/main/install.sh | bash
3
+ # Usage: curl -fsSL https://raw.githubusercontent.com/zeenie-ai/MachinaOS/main/install.sh | bash
4
4
  #
5
5
  # This script installs MachinaOS and its dependencies:
6
6
  # - Node.js 22+ (via brew/apt/dnf/pacman)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "machinaos",
3
- "version": "0.0.77",
3
+ "version": "0.0.78",
4
4
  "description": "Open source workflow automation platform with AI agents, React Flow, and n8n-inspired architecture",
5
5
  "type": "module",
6
6
  "keywords": [
@@ -18,13 +18,13 @@
18
18
  ],
19
19
  "author": "Rohit G <trohitg@gmail.com>",
20
20
  "license": "MIT",
21
- "homepage": "https://github.com/trohitg/MachinaOS#readme",
21
+ "homepage": "https://github.com/zeenie-ai/MachinaOS#readme",
22
22
  "repository": {
23
23
  "type": "git",
24
- "url": "git+https://github.com/trohitg/MachinaOS.git"
24
+ "url": "git+https://github.com/zeenie-ai/MachinaOS.git"
25
25
  },
26
26
  "bugs": {
27
- "url": "https://github.com/trohitg/MachinaOS/issues"
27
+ "url": "https://github.com/zeenie-ai/MachinaOS/issues"
28
28
  },
29
29
  "bin": {
30
30
  "machina": "./bin/cli.js"
@@ -10,14 +10,14 @@
10
10
  "dev": "tsx watch src/index.ts"
11
11
  },
12
12
  "dependencies": {
13
- "express": "^5.0.0"
13
+ "express": "^5.2.1"
14
14
  },
15
15
  "devDependencies": {
16
- "@types/express": "^5.0.0",
17
- "@types/node": "^22.0.0",
18
- "esbuild": "^0.24.0",
16
+ "@types/express": "^5.0.6",
17
+ "@types/node": "^22.19.18",
18
+ "esbuild": "^0.25.0",
19
19
  "tsx": "^4.21.0",
20
- "typescript": "^5.7.0"
20
+ "typescript": "^5.9.3"
21
21
  },
22
22
  "engines": {
23
23
  "node": ">=22.0.0"
@@ -5,7 +5,7 @@
5
5
 
6
6
  import express, { Request, Response, NextFunction } from 'express';
7
7
  import vm from 'node:vm';
8
- import { execSync } from 'node:child_process';
8
+ import { execFileSync } from 'node:child_process';
9
9
  import path from 'node:path';
10
10
  import { fileURLToPath } from 'node:url';
11
11
 
@@ -65,6 +65,14 @@ app.post('/execute', (req: Request, res: Response) => {
65
65
 
66
66
  try {
67
67
  const context = vm.createContext(sandbox);
68
+ // This service IS the sandboxed JS executor for the pythonExecutor /
69
+ // javascriptExecutor workflow nodes. Node's `vm` is not a security
70
+ // boundary (per https://nodejs.org/api/vm.html#vmcreatecontextcontextobject-options);
71
+ // the deployment context is: server binds to localhost only (line 16,
72
+ // default 'localhost') and is invoked exclusively by the same-machine
73
+ // Python backend via NodeJSClient. Public network exposure is the
74
+ // operator's responsibility.
75
+ // codeql[js/code-injection]
68
76
  vm.runInContext(code, context, { timeout, filename: 'user-code.js' });
69
77
 
70
78
  res.json({
@@ -83,7 +91,11 @@ app.post('/execute', (req: Request, res: Response) => {
83
91
  }
84
92
  });
85
93
 
86
- // Install packages - package list from request
94
+ // Install packages - package list from request.
95
+ // Localhost-only service (see server.listen at the bottom); same trust
96
+ // boundary as the /execute sandbox. No request-rate limiting because the
97
+ // only caller is the same-machine Python backend.
98
+ // codeql[js/missing-rate-limiting]
87
99
  app.post('/packages/install', (req: Request, res: Response) => {
88
100
  const { packages } = req.body as { packages: string[] };
89
101
 
@@ -100,17 +112,22 @@ app.post('/packages/install', (req: Request, res: Response) => {
100
112
  }
101
113
 
102
114
  try {
103
- execSync(`npm install ${packages.join(' ')}`, { cwd: USER_PACKAGES_DIR, timeout: 60000 });
115
+ // execFileSync (argv array, no shell) instead of execSync with template
116
+ // string. The regex above already validates names, but going through
117
+ // execFileSync removes the shell from the path entirely as
118
+ // defense-in-depth.
119
+ execFileSync('npm', ['install', ...packages], { cwd: USER_PACKAGES_DIR, timeout: 60000 });
104
120
  res.json({ success: true, message: `Installed: ${packages.join(', ')}` });
105
121
  } catch (error) {
106
122
  res.status(500).json({ success: false, error: error instanceof Error ? error.message : String(error) });
107
123
  }
108
124
  });
109
125
 
110
- // List packages
126
+ // List packages — same localhost-only trust boundary as above.
127
+ // codeql[js/missing-rate-limiting]
111
128
  app.get('/packages', (_req: Request, res: Response) => {
112
129
  try {
113
- const output = execSync('npm list --json --depth=0', { cwd: USER_PACKAGES_DIR, encoding: 'utf-8' });
130
+ const output = execFileSync('npm', ['list', '--json', '--depth=0'], { cwd: USER_PACKAGES_DIR, encoding: 'utf-8' });
114
131
  res.json({ success: true, packages: JSON.parse(output).dependencies || {} });
115
132
  } catch {
116
133
  res.json({ success: true, packages: {} });
@@ -1,6 +1,8 @@
1
1
  """Android System Services routes."""
2
2
 
3
- from fastapi import APIRouter, Depends
3
+ import re
4
+
5
+ from fastapi import APIRouter, Depends, HTTPException
4
6
  from pydantic import BaseModel, Field
5
7
  from typing import Dict, Any
6
8
 
@@ -11,6 +13,20 @@ from services.plugin.deps import get_android_service
11
13
  logger = get_logger(__name__)
12
14
  router = APIRouter(prefix="/api/android", tags=["android"])
13
15
 
16
+ # ADB device IDs: USB serials (alphanumeric), TCP "host:port" (digits + dots
17
+ # + colon), or "emulator-NNNN". All are safe characters but we lock the
18
+ # accepted set explicitly so untrusted input can't slip a flag or path
19
+ # separator into the argv list we pass to subprocess.run. Anything outside
20
+ # `[A-Za-z0-9._:-]` (and longer than 64 chars) is rejected with 400.
21
+ _DEVICE_ID_PATTERN = re.compile(r"^[A-Za-z0-9._:-]{1,64}$")
22
+
23
+
24
+ def _validate_device_id(device_id: str) -> str:
25
+ """Return device_id if it matches the ADB device-id shape, else 400."""
26
+ if not _DEVICE_ID_PATTERN.fullmatch(device_id):
27
+ raise HTTPException(status_code=400, detail="invalid device_id")
28
+ return device_id
29
+
14
30
 
15
31
  class AndroidServiceRequest(BaseModel):
16
32
  """Request model for Android service execution."""
@@ -195,9 +211,12 @@ async def setup_port_forwarding(
195
211
  device_port: int = 8888
196
212
  ):
197
213
  """Setup ADB port forwarding for Android device communication."""
214
+ device_id = _validate_device_id(device_id)
198
215
  import subprocess
199
216
  try:
200
217
  # Setup port forwarding: adb -s device_id forward tcp:local_port tcp:device_port
218
+ # device_id passes _DEVICE_ID_PATTERN above; subprocess.run is called
219
+ # with an argv list (no shell), so no further interpolation risk.
201
220
  cmd = ["adb", "-s", device_id, "forward", f"tcp:{local_port}", f"tcp:{device_port}"]
202
221
 
203
222
  result = subprocess.run(
@@ -43,24 +43,25 @@ dependencies = [
43
43
  "cryptography>=44.0.0",
44
44
 
45
45
  # AI - All providers (directly imported in ai.py)
46
- # Versions pinned to exactly match the main branch so that the LangGraph
47
- # agent loop behaves identically. The `response.tool_calls` empty-payload
48
- # regression on tool_use responses appears to come from a library skew
49
- # somewhere in this set; lockstepping with main eliminates it as a
50
- # variable. Lift these pins when the upstream cause is identified.
51
- "langchain-core==1.2.28",
52
- "langchain-openai==1.1.12",
46
+ # Originally pinned to lockstep with main to neutralise a tool_calls
47
+ # empty-payload regression. Lifted to 1.3.x in response to security
48
+ # advisories GHSA-jcc3-qxqm-r62h (unsafe deserialization in
49
+ # langchain-core <=1.3.2), the langchain-openai DNS-rebinding SSRF
50
+ # advisory (<1.1.14), and the langchain-text-splitters SSRF advisory
51
+ # (<1.1.2). Full backend suite (1018/1018) re-validated after the bump.
52
+ "langchain-core==1.3.3",
53
+ "langchain-openai==1.1.14",
53
54
  "langchain-anthropic==1.4.0",
54
55
  "anthropic==0.94.0",
55
56
  "langchain-google-genai==4.2.1",
56
57
  "google-genai==1.72.0",
57
58
  "langchain-groq==1.1.2",
58
59
  "langchain-cerebras==0.8.2",
59
- # textChunker plugin (recursive / markdown / token strategies). Pinned to
60
- # 1.0.0 the only release in the 1.x line whose `langchain-core` floor
61
- # (>=0.3.72,<2.0.0) is compatible with our pinned `langchain-core==1.2.28`.
62
- # Bumping to 1.1+ pulls langchain-core>=1.3 and breaks the lockstep.
63
- "langchain-text-splitters==1.0.0",
60
+ # textChunker plugin (recursive / markdown / token strategies). Bumped
61
+ # to 1.1.2+ alongside langchain-core 1.3.3 to clear the
62
+ # HTMLHeaderTextSplitter SSRF advisory; the 1.1 line requires
63
+ # langchain-core>=1.3, which we now satisfy.
64
+ "langchain-text-splitters==1.1.2",
64
65
  "langgraph==1.1.6",
65
66
  "deepagents==0.5.2",
66
67
 
@@ -1 +0,0 @@
1
- import{f as u,n as d,o as p,p as m,q as f,r as g,k as x}from"./index-DNx1tG6T.js";import{j as l}from"./vendor-radix-BGeDhy8U.js";import{ac as b}from"./vendor-icons-BPyNc2rK.js";function h(r){const t=u.c(7),a=d(),n=p(),s=m(),i=f(),o=g();if(!r)return null;let e;return t[0]!==n||t[1]!==i||t[2]!==r||t[3]!==s||t[4]!==o||t[5]!==a?(e={whatsapp:a,android:n,twitter:s,google:i,telegram:o}[r]??null,t[0]=n,t[1]=i,t[2]=r,t[3]=s,t[4]=o,t[5]=a,t[6]=e):e=t[6],e}const y=r=>{const t=u.c(7),{actions:a,loading:n}=r;let s;if(t[0]!==a||t[1]!==n){let o;t[3]!==n?(o=e=>{const c=n===e.key;return l.jsxs(x,{intent:e.intent,onClick:e.onClick,disabled:e.disabled||c,children:[c?l.jsx(b,{className:"h-4 w-4 animate-spin"}):e.icon,e.label]},e.key)},t[3]=n,t[4]=o):o=t[4],s=a.filter(j).map(o),t[0]=a,t[1]=n,t[2]=s}else s=t[2];let i;return t[5]!==s?(i=l.jsx("div",{className:"flex justify-center gap-2 border-t border-border pt-3",children:s}),t[5]=s,t[6]=i):i=t[6],i};function j(r){return!r.hidden}export{y as A,h as u};
@@ -1 +0,0 @@
1
- import{j as s}from"./vendor-radix-BGeDhy8U.js";import{b as j}from"./vendor-react-CxXU_nq3.js";import{I as u,B as c}from"./index-DNx1tG6T.js";import{bb as d,bc as N,ac as b,aj as v,ap as w,aa as y}from"./vendor-icons-BPyNc2rK.js";const I=({value:l,onChange:n,onSave:m,onDelete:i,placeholder:x="Enter API key...",loading:o=!1,isStored:a=!1,disabled:e=!1,saveLabel:h="Validate",savedLabel:p="Valid"})=>{const[t,f]=j.useState(!1);return s.jsxs("div",{className:"flex w-full items-stretch gap-1",children:[s.jsxs("div",{className:"relative flex-1",children:[s.jsx(u,{type:t?"text":"password",value:l,onChange:r=>n(r.target.value),placeholder:x,disabled:e,className:"font-mono pr-9"}),s.jsx("button",{type:"button",onClick:()=>f(r=>!r),className:"absolute top-1/2 right-2 -translate-y-1/2 text-muted-foreground hover:text-foreground","aria-label":t?"Hide key":"Show key",children:t?s.jsx(d,{className:"h-4 w-4"}):s.jsx(N,{className:"h-4 w-4"})})]}),s.jsxs(c,{variant:"default",onClick:m,disabled:!l.trim()||e||o,children:[o?s.jsx(b,{className:"h-4 w-4 animate-spin"}):a?s.jsx(v,{className:"h-4 w-4"}):s.jsx(w,{className:"h-4 w-4"}),a?p:h]}),a&&i&&s.jsx(c,{variant:"destructive",size:"icon",onClick:i,disabled:e,children:s.jsx(y,{className:"h-4 w-4"})})]})};export{I as A};
@@ -1 +0,0 @@
1
- import{j as s}from"./vendor-radix-BGeDhy8U.js";import{u as E,A as V,a as P,b as U,c as z,d as R,e as K,B as H,f as F,N as M,C as O,g as q,h as G,i as I,j as T,L as J,I as Q,k as W}from"./index-DNx1tG6T.js";import{A as X}from"./ApiKeyInput-DljozMIZ.js";import{u as Y,P as Z}from"./RateLimitSection-B2lBVQs0.js";import{b as A}from"./vendor-react-CxXU_nq3.js";import{ba as ee,ac as L,b7 as se,aj as ae}from"./vendor-icons-BPyNc2rK.js";import{A as te}from"./ApiUsageSection-FWVtg8Sd.js";import"./vendor-flow-apeQB2hf.js";import"./vendor-query-to9T1kjL.js";import"./vendor-misc-4my8ai2A.js";import"./vendor-markdown-Bx_GU1E7.js";const D=N=>{const e=F.c(8),{label:t,value:p,className:a}=N;let l;e[0]!==t?(l=s.jsx("span",{className:"text-xs text-muted-foreground",children:t}),e[0]=t,e[1]=l):l=e[1];const n=`text-lg font-semibold ${a??""}`;let i;e[2]!==n||e[3]!==p?(i=s.jsx("span",{className:n,children:p}),e[2]=n,e[3]=p,e[4]=i):i=e[4];let o;return e[5]!==l||e[6]!==i?(o=s.jsxs("div",{className:"flex flex-col",children:[l,i]}),e[5]=l,e[6]=i,e[7]=o):o=e[7],o},le=({providerId:N,providerName:e})=>{const{getProviderUsageSummary:t,isConnected:p}=E(),[a,l]=A.useState(null),[n,i]=A.useState(!1),[o,h]=A.useState(!1),d=A.useCallback(async()=>{if(p){i(!0);try{const r=await t();l(r.find(c=>c.provider===N)??null)}finally{i(!1)}}},[p,N,t]);return A.useEffect(()=>{o&&d()},[o,d]),s.jsx(V,{type:"single",collapsible:!0,onValueChange:r=>h(r==="usage"),children:s.jsxs(P,{value:"usage",children:[s.jsx(U,{children:s.jsxs("span",{className:"flex items-center gap-2",children:[s.jsx(ee,{className:"h-4 w-4"})," Usage & Costs"]})}),s.jsx(z,{children:n?s.jsx("div",{className:"flex justify-center p-4",children:s.jsx(L,{className:"h-4 w-4 animate-spin text-muted-foreground"})}):!a||a.execution_count===0?s.jsx(R,{variant:"info",children:s.jsxs(K,{children:["No usage data yet for ",e]})}):s.jsxs("div",{className:"flex w-full flex-col gap-4",children:[s.jsxs("div",{className:"flex flex-wrap gap-4",children:[s.jsx(D,{label:"Total Tokens",value:a.total_tokens.toLocaleString(),className:"text-dracula-cyan"}),s.jsx(D,{label:"Total Cost",value:`$${a.total_cost.toFixed(4)}`,className:"text-dracula-green"}),s.jsx(D,{label:"Executions",value:a.execution_count,className:"text-dracula-purple"})]}),s.jsxs("div",{className:"overflow-hidden rounded-md border border-border",children:[s.jsxs("div",{className:"grid grid-cols-2 divide-x divide-border border-b border-border",children:[s.jsxs("div",{className:"px-3 py-2 text-sm",children:[s.jsx("div",{className:"text-xs text-muted-foreground",children:"Input Tokens"}),s.jsxs("div",{children:[a.total_input_tokens.toLocaleString()," ",s.jsxs("span",{className:"ml-1 text-dracula-green",children:["($",a.total_input_cost.toFixed(4),")"]})]})]}),s.jsxs("div",{className:"px-3 py-2 text-sm",children:[s.jsx("div",{className:"text-xs text-muted-foreground",children:"Output Tokens"}),s.jsxs("div",{children:[a.total_output_tokens.toLocaleString()," ",s.jsxs("span",{className:"ml-1 text-dracula-green",children:["($",a.total_output_cost.toFixed(4),")"]})]})]})]}),a.total_cache_cost>0&&s.jsxs("div",{className:"px-3 py-2 text-sm",children:[s.jsx("span",{className:"text-xs text-muted-foreground",children:"Cache Cost: "}),s.jsxs("span",{className:"text-dracula-green",children:["$",a.total_cache_cost.toFixed(4)]})]})]}),a.models.length>1&&s.jsxs("div",{className:"overflow-hidden rounded-md border border-border",children:[s.jsx("div",{className:"border-b border-border bg-muted px-3 py-1.5 text-xs font-semibold",children:"By Model"}),s.jsx("div",{className:"divide-y divide-border",children:a.models.map(r=>s.jsxs("div",{className:"grid grid-cols-[1fr_auto] items-center gap-3 px-3 py-2 text-sm",children:[s.jsx("code",{className:"text-xs",children:r.model}),s.jsxs("span",{className:"text-dracula-green",children:["$",r.total_cost.toFixed(4)]})]},r.model))})]}),s.jsxs(H,{size:"sm",variant:"outline",onClick:d,disabled:n,children:[n?s.jsx(L,{className:"h-3 w-3 animate-spin"}):s.jsx(se,{className:"h-3 w-3"}),"Refresh"]})]})})]})})},ve=N=>{const e=F.c(71),{config:t,visible:p}=N,a=Y(t,p),l=t.fields?.[0];let n,i,o,h;if(e[0]!==t.color||e[1]!==t.fields||e[2]!==t.iconRef||e[3]!==t.id||e[4]!==t.name||e[5]!==l||e[6]!==a.actions||e[7]!==a.error||e[8]!==a.form||e[9]!==a.loading||e[10]!==a.stored||e[11]!==a.values){const _=(t.fields??[]).slice(1),g=l?a.values[l.key]??"":"",x=a.stored;n="flex flex-col gap-5 p-5";let m;e[16]!==t.color?(m={color:t.color},e[16]=t.color,e[17]=m):m=e[17];let u;e[18]!==t.iconRef?(u=s.jsx(M,{icon:t.iconRef,className:"h-12 w-12 text-2xl"}),e[18]=t.iconRef,e[19]=u):u=e[19];let f;e[20]!==m||e[21]!==u?(f=s.jsx("div",{className:"rounded-lg bg-tint-soft",style:m,children:u}),e[20]=m,e[21]=u,e[22]=f):f=e[22];let j;e[23]!==t.name?(j=s.jsx(O,{className:"text-lg",children:t.name}),e[23]=t.name,e[24]=j):j=e[24];let b;e[25]!==f||e[26]!==j?(b=s.jsxs("div",{className:"flex items-center gap-3",children:[f,j]}),e[25]=f,e[26]=j,e[27]=b):b=e[27];let C;e[28]!==x?(C=x&&s.jsxs(q,{variant:"success",className:"gap-1",children:[s.jsx(ae,{className:"h-3 w-3"}),"Connected"]}),e[28]=x,e[29]=C):C=e[29];let k;e[30]!==C||e[31]!==b?(k=s.jsxs(G,{className:"flex flex-row items-center justify-between gap-3 space-y-0 pb-3",children:[b,C]}),e[30]=C,e[31]=b,e[32]=k):k=e[32];let S;e[33]!==t.id||e[34]!==l||e[35]!==g||e[36]!==a.actions||e[37]!==a.form||e[38]!==a.loading||e[39]!==x?(S=l&&s.jsx(X,{value:g,onChange:v=>a.form.setFieldValue(l.key,v),onSave:()=>a.actions.validate(t.id,g.trim()),onDelete:x?async()=>{await a.actions.remove(t.id),l.key!=="apiKey"&&await a.actions.remove(l.key)}:void 0,placeholder:l.placeholder,loading:a.loading==="validate",isStored:x,saveLabel:l.key==="apiKey"?"Validate":"Fetch",savedLabel:l.key==="apiKey"?"Valid":"Connected"}),e[33]=t.id,e[34]=l,e[35]=g,e[36]=a.actions,e[37]=a.form,e[38]=a.loading,e[39]=x,e[40]=S):S=e[40];let w;e[41]!==S?(w=s.jsx(I,{children:S}),e[41]=S,e[42]=w):w=e[42],e[43]!==k||e[44]!==w?(i=s.jsxs(T,{children:[k,w]}),e[43]=k,e[44]=w,e[45]=i):i=e[45],e[46]!==a.error?(o=a.error&&s.jsx(R,{variant:"destructive",children:s.jsx(K,{children:a.error})}),e[46]=a.error,e[47]=o):o=e[47];let $;e[48]!==a.actions||e[49]!==a.form||e[50]!==a.loading||e[51]!==a.values?($=v=>s.jsx(ie,{fieldKey:v.key,label:v.label,placeholder:v.placeholder,help:v.help,secret:v.secret,value:a.values[v.key]??"",onChange:B=>a.form.setFieldValue(v.key,B),onSave:()=>a.actions.save(v.key,a.values[v.key]??""),loading:a.loading==="save"},v.key),e[48]=a.actions,e[49]=a.form,e[50]=a.loading,e[51]=a.values,e[52]=$):$=e[52],h=_.map($),e[0]=t.color,e[1]=t.fields,e[2]=t.iconRef,e[3]=t.id,e[4]=t.name,e[5]=l,e[6]=a.actions,e[7]=a.error,e[8]=a.form,e[9]=a.loading,e[10]=a.stored,e[11]=a.values,e[12]=n,e[13]=i,e[14]=o,e[15]=h}else n=e[12],i=e[13],o=e[14],h=e[15];let d;e[53]!==t.hasDefaults||e[54]!==t.id?(d=t.hasDefaults&&s.jsx(Z,{providerId:t.id}),e[53]=t.hasDefaults,e[54]=t.id,e[55]=d):d=e[55];let r;e[56]!==t.hasDefaults||e[57]!==t.id||e[58]!==t.name?(r=t.hasDefaults&&s.jsx(le,{providerId:t.id,providerName:t.name}),e[56]=t.hasDefaults,e[57]=t.id,e[58]=t.name,e[59]=r):r=e[59];let c;e[60]!==t.name||e[61]!==t.usageService?(c=t.usageService&&s.jsx(te,{service:t.usageService,serviceName:t.name}),e[60]=t.name,e[61]=t.usageService,e[62]=c):c=e[62];let y;return e[63]!==n||e[64]!==i||e[65]!==o||e[66]!==h||e[67]!==d||e[68]!==r||e[69]!==c?(y=s.jsxs("div",{className:n,children:[i,o,h,d,r,c]}),e[63]=n,e[64]=i,e[65]=o,e[66]=h,e[67]=d,e[68]=r,e[69]=c,e[70]=y):y=e[70],y},ie=N=>{const e=F.c(23),{fieldKey:t,label:p,placeholder:a,help:l,secret:n,value:i,onChange:o,onSave:h,loading:d}=N,r=`cred-${t}`;let c;e[0]!==p||e[1]!==r?(c=s.jsx(J,{htmlFor:r,className:"text-sm font-medium",children:p}),e[0]=p,e[1]=r,e[2]=c):c=e[2];const y=`cred-${t}`,_=n?"password":"text";let g;e[3]!==o?(g=b=>o(b.target.value),e[3]=o,e[4]=g):g=e[4];let x;e[5]!==a||e[6]!==y||e[7]!==_||e[8]!==g||e[9]!==i?(x=s.jsx(Q,{id:y,type:_,value:i,onChange:g,placeholder:a,className:"flex-1"}),e[5]=a,e[6]=y,e[7]=_,e[8]=g,e[9]=i,e[10]=x):x=e[10];let m;e[11]!==d||e[12]!==h?(m=s.jsx(W,{intent:"save",onClick:h,disabled:d,children:"Save"}),e[11]=d,e[12]=h,e[13]=m):m=e[13];let u;e[14]!==x||e[15]!==m?(u=s.jsxs("div",{className:"flex gap-2",children:[x,m]}),e[14]=x,e[15]=m,e[16]=u):u=e[16];let f;e[17]!==l?(f=l&&s.jsx("p",{className:"text-xs text-muted-foreground",children:l}),e[17]=l,e[18]=f):f=e[18];let j;return e[19]!==c||e[20]!==u||e[21]!==f?(j=s.jsx(T,{children:s.jsxs(I,{className:"flex flex-col gap-2 pt-4",children:[c,u,f]})}),e[19]=c,e[20]=u,e[21]=f,e[22]=j):j=e[22],j};export{ve as default};
@@ -1 +0,0 @@
1
- import{j as e}from"./vendor-radix-BGeDhy8U.js";import{u as h,g as u,A as g,a as b,b as v,c as N,d as y,e as w,B as A,f as C}from"./index-DNx1tG6T.js";import{b as x}from"./vendor-react-CxXU_nq3.js";import{ba as _,ac as f,b7 as S}from"./vendor-icons-BPyNc2rK.js";const E=({service:d,serviceName:s})=>{const{getAPIUsageSummary:c,isConnected:i}=h(),[a,l]=x.useState(null),[o,t]=x.useState(!1),r=x.useCallback(async()=>{if(i){t(!0);try{const n=await c(d);l(n.find(j=>j.service===d)??null)}finally{t(!1)}}},[i,d,c]);x.useEffect(()=>{r()},[r]);const p=a?e.jsxs(u,{variant:"success",children:["$",a.total_cost.toFixed(4)]}):null;return e.jsx(g,{type:"single",collapsible:!0,children:e.jsxs(b,{value:"usage",children:[e.jsx(v,{children:e.jsxs("span",{className:"flex items-center gap-2",children:[e.jsx(_,{className:"h-4 w-4 text-dracula-yellow"}),"API Usage & Costs ",p]})}),e.jsx(N,{children:o?e.jsx("div",{className:"flex justify-center p-4",children:e.jsx(f,{className:"h-4 w-4 animate-spin text-muted-foreground"})}):a?e.jsxs("div",{className:"flex w-full flex-col gap-4",children:[e.jsxs("div",{className:"flex flex-wrap gap-4",children:[e.jsx(m,{label:"Total Cost",value:`$${a.total_cost.toFixed(4)}`,className:"text-dracula-green"}),e.jsx(m,{label:"API Calls",value:a.execution_count,className:"text-dracula-cyan"}),e.jsx(m,{label:"Resources",value:a.total_resources,className:"text-dracula-purple"})]}),a.operations?.length>0&&e.jsxs("div",{className:"overflow-hidden rounded-md border border-border",children:[e.jsx("div",{className:"border-b border-border bg-muted px-3 py-1.5 text-xs font-semibold",children:"Operations Breakdown"}),e.jsx("div",{className:"divide-y divide-border",children:a.operations.map(n=>e.jsxs("div",{className:"grid grid-cols-[1fr_auto] items-center gap-3 px-3 py-2 text-sm",children:[e.jsx("code",{className:"text-xs text-muted-foreground",children:n.operation}),e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsxs(u,{variant:"outline",children:[n.resource_count," resources"]}),e.jsxs(u,{variant:"success",children:["$",n.total_cost.toFixed(4)]})]})]},n.operation))})]}),e.jsxs(A,{size:"sm",variant:"outline",onClick:r,disabled:o,children:[o?e.jsx(f,{className:"h-3 w-3 animate-spin"}):e.jsx(S,{className:"h-3 w-3"}),"Refresh"]})]}):e.jsx(y,{variant:"info",children:e.jsxs(w,{children:["No usage data yet. Use ",s," nodes in your workflows to track costs."]})})})]})})},m=d=>{const s=C.c(8),{label:c,value:i,className:a}=d;let l;s[0]!==c?(l=e.jsx("span",{className:"text-xs text-muted-foreground",children:c}),s[0]=c,s[1]=l):l=s[1];const o=`text-lg font-semibold ${a??""}`;let t;s[2]!==o||s[3]!==i?(t=e.jsx("span",{className:o,children:i}),s[2]=o,s[3]=i,s[4]=t):t=s[4];let r;return s[5]!==l||s[6]!==t?(r=e.jsxs("div",{className:"flex flex-col",children:[l,t]}),s[5]=l,s[6]=t,s[7]=r):r=s[7],r};export{E as A};
@@ -1 +0,0 @@
1
- import{j as e}from"./vendor-radix-BGeDhy8U.js";import{b as l,h as B}from"./vendor-react-CxXU_nq3.js";import{v as G,P as I,R as j,_ as Y,T as z,u as J,t as Q,N as W,F as X,w as m,x as n,y as d,z as Z,D as c,E as $,G as ee,H as se,J as ae,M as p,I as f,K as re,d as oe,e as te,k as M}from"./index-DNx1tG6T.js";import{S as ie}from"./StatusCard-BlufvZD-.js";import{bb as le,bc as me,ac as F}from"./vendor-icons-BPyNc2rK.js";import"./vendor-flow-apeQB2hf.js";import"./vendor-query-to9T1kjL.js";import"./vendor-misc-4my8ai2A.js";import"./vendor-markdown-Bx_GU1E7.js";const R=[{label:"Gmail",value:"gmail"},{label:"Outlook / Office 365",value:"outlook"},{label:"Yahoo Mail",value:"yahoo"},{label:"iCloud Mail",value:"icloud"},{label:"ProtonMail (Bridge)",value:"protonmail"},{label:"Fastmail",value:"fastmail"},{label:"Custom / Self-hosted",value:"custom"}],ne={gmail:"Use an App Password from Google Account > Security > 2-Step Verification.",outlook:"Use your account password or an App Password.",yahoo:"Use an App Password from Yahoo Account Security.",icloud:"Use an App-Specific Password from your Apple ID.",protonmail:"Requires ProtonMail Bridge running locally (127.0.0.1).",fastmail:"Use an App Password from Settings > Privacy & Security.",custom:"Enter credentials for your self-hosted IMAP/SMTP server below."},de=R.map(u=>u.value);function ce(u){return G({provider:Y(de),address:j().min(1,"Email address is required").pipe(z("Enter a valid email address")),password:u?j().min(1,"Password is required"):j().optional(),imapHost:j().optional(),imapPort:I().int().min(1).max(65535).optional(),smtpHost:j().optional(),smtpPort:I().int().min(1).max(65535).optional()}).superRefine((x,o)=>{x.provider==="custom"&&(x.imapHost?.trim()||o.addIssue({code:"custom",path:["imapHost"],message:"IMAP host is required for custom provider"}),x.smtpHost?.trim()||o.addIssue({code:"custom",path:["smtpHost"],message:"SMTP host is required for custom provider"}))})}const T={provider:"gmail",address:"",password:"",imapHost:"",imapPort:993,smtpHost:"",smtpPort:465},we=({config:u,visible:x})=>{const{saveApiKey:o,getStoredApiKey:h,hasStoredKey:k,removeApiKey:t,isConnected:_}=J(),[i,v]=l.useState(!1),[b,S]=l.useState(""),[P,g]=l.useState(null),[N,w]=l.useState(null),[y,U]=l.useState(!1),V=l.useMemo(()=>ce(!i),[i]),r=B({resolver:Q(V),defaultValues:T,mode:"onSubmit"}),A=r.watch("provider");l.useEffect(()=>{if(!x||!_)return;let s=!1;return(async()=>{try{const[a,H,K,L,E,q,C]=await Promise.all([h("email_provider"),h("email_address"),k("email_password"),h("email_imap_host"),h("email_imap_port"),h("email_smtp_host"),h("email_smtp_port")]);if(s)return;r.reset({provider:a||"gmail",address:H||"",password:"",imapHost:L||"",imapPort:E?parseInt(E,10):993,smtpHost:q||"",smtpPort:C?parseInt(C,10):465}),S(H||""),v(K)}catch{s||v(!1)}})(),()=>{s=!0}},[x,_]);const O=async s=>{g("save"),w(null);try{await o("email_provider",s.provider),await o("email_address",s.address.trim()),s.password?.trim()&&await o("email_password",s.password.trim()),s.provider==="custom"&&(s.imapHost&&await o("email_imap_host",s.imapHost.trim()),s.imapPort!=null&&await o("email_imap_port",String(s.imapPort)),s.smtpHost&&await o("email_smtp_host",s.smtpHost.trim()),s.smtpPort!=null&&await o("email_smtp_port",String(s.smtpPort))),v(!0),S(s.address.trim()),r.setValue("password","")}catch(a){w(a.message||"Failed to save email credentials")}finally{g(null)}},D=async()=>{g("remove"),w(null);try{await Promise.all([t("email_password"),t("email_address"),t("email_provider"),t("email_imap_host"),t("email_imap_port"),t("email_smtp_host"),t("email_smtp_port")]),v(!1),S(""),r.reset(T)}catch(s){w(s.message||"Failed to remove credentials")}finally{g(null)}};return e.jsxs("div",{className:"flex min-h-0 flex-1 flex-col gap-4 p-5",children:[e.jsx(ie,{icon:e.jsx(W,{icon:u.iconRef,className:"h-6 w-6 text-2xl"}),title:u.name,status:{stored:i,address:b},rows:[{label:"Status",ok:s=>s.stored,trueText:"Configured",falseText:"Not configured"},...i&&b?[{label:"Account",ok:()=>!0,trueText:b,falseText:""}]:[]]}),e.jsx(X,{...r,children:e.jsxs("form",{id:"email-form",onSubmit:r.handleSubmit(O),className:"flex flex-col gap-4",children:[e.jsx(m,{control:r.control,name:"provider",render:({field:s})=>e.jsxs(n,{children:[e.jsx(d,{children:"Provider"}),e.jsxs(Z,{value:s.value,onValueChange:s.onChange,children:[e.jsx(c,{children:e.jsx($,{children:e.jsx(ee,{placeholder:"Choose a provider"})})}),e.jsx(se,{children:R.map(a=>e.jsx(ae,{value:a.value,children:a.label},a.value))})]}),e.jsx(p,{})]})}),e.jsx(m,{control:r.control,name:"address",render:({field:s})=>e.jsxs(n,{children:[e.jsx(d,{children:"Email Address"}),e.jsx(c,{children:e.jsx(f,{placeholder:"you@example.com",...s})}),e.jsx(p,{})]})}),e.jsx(m,{control:r.control,name:"password",render:({field:s})=>e.jsxs(n,{children:[e.jsxs(d,{className:"flex items-center gap-2",children:["Password",i&&e.jsx("span",{className:"text-xs font-normal text-muted-foreground",children:"(leave blank to keep existing)"})]}),e.jsx(c,{children:e.jsxs("div",{className:"relative",children:[e.jsx(f,{type:y?"text":"password",placeholder:i?"••••••••":"App password or account password",className:"font-mono pr-9",...s}),e.jsx("button",{type:"button",onClick:()=>U(a=>!a),className:"absolute top-1/2 right-2 -translate-y-1/2 text-muted-foreground hover:text-foreground","aria-label":y?"Hide password":"Show password",children:y?e.jsx(le,{className:"h-4 w-4"}):e.jsx(me,{className:"h-4 w-4"})})]})}),e.jsx(re,{children:ne[A]}),e.jsx(p,{})]})}),A==="custom"&&e.jsxs("div",{className:"rounded-md border border-border bg-muted p-3",children:[e.jsx("div",{className:"mb-3 text-sm font-medium",children:"Custom IMAP / SMTP"}),e.jsxs("div",{className:"flex gap-3",children:[e.jsx(m,{control:r.control,name:"imapHost",render:({field:s})=>e.jsxs(n,{className:"flex-[2]",children:[e.jsx(d,{children:"IMAP Host"}),e.jsx(c,{children:e.jsx(f,{placeholder:"imap.example.com",...s})}),e.jsx(p,{})]})}),e.jsx(m,{control:r.control,name:"imapPort",render:({field:s})=>e.jsxs(n,{className:"flex-1",children:[e.jsx(d,{children:"IMAP Port"}),e.jsx(c,{children:e.jsx(f,{type:"number",min:1,max:65535,...s,value:s.value??"",onChange:a=>s.onChange(a.target.value===""?void 0:Number(a.target.value))})}),e.jsx(p,{})]})})]}),e.jsxs("div",{className:"mt-3 flex gap-3",children:[e.jsx(m,{control:r.control,name:"smtpHost",render:({field:s})=>e.jsxs(n,{className:"flex-[2]",children:[e.jsx(d,{children:"SMTP Host"}),e.jsx(c,{children:e.jsx(f,{placeholder:"smtp.example.com",...s})}),e.jsx(p,{})]})}),e.jsx(m,{control:r.control,name:"smtpPort",render:({field:s})=>e.jsxs(n,{className:"flex-1",children:[e.jsx(d,{children:"SMTP Port"}),e.jsx(c,{children:e.jsx(f,{type:"number",min:1,max:65535,...s,value:s.value??"",onChange:a=>s.onChange(a.target.value===""?void 0:Number(a.target.value))})}),e.jsx(p,{})]})})]})]})]})}),N&&e.jsx(oe,{variant:"destructive",children:e.jsx(te,{children:N})}),e.jsx("div",{className:"flex-1"}),e.jsxs("div",{className:"flex justify-center gap-2 border-t border-border pt-3",children:[e.jsxs(M,{intent:"save",type:"submit",form:"email-form",disabled:P==="save",children:[P==="save"&&e.jsx(F,{className:"h-4 w-4 animate-spin"}),"Save"]}),i&&e.jsxs(M,{intent:"stop",type:"button",onClick:D,disabled:P==="remove",children:[P==="remove"&&e.jsx(F,{className:"h-4 w-4 animate-spin"}),"Remove"]})]})]})};export{we as default};
@@ -1 +0,0 @@
1
- import{j as l}from"./vendor-radix-BGeDhy8U.js";import{f as O,L as P,I as B,k as D,d as H,e as z,N as Y}from"./index-DNx1tG6T.js";import{u as G}from"./RateLimitSection-B2lBVQs0.js";import{A as J,u as K}from"./ActionBar-DAHXJmEU.js";import{b as I}from"./vendor-react-CxXU_nq3.js";import{bb as M,bc as Q,ac as W,aq as X}from"./vendor-icons-BPyNc2rK.js";import{S as Z}from"./StatusCard-BlufvZD-.js";import{A as ee}from"./ApiUsageSection-FWVtg8Sd.js";import"./vendor-flow-apeQB2hf.js";import"./vendor-query-to9T1kjL.js";import"./vendor-misc-4my8ai2A.js";import"./vendor-markdown-Bx_GU1E7.js";const te=i=>{const e=O.c(7),{fields:t,form:c}=i;let s;if(e[0]!==t||e[1]!==c){let n;e[3]!==c?(n=o=>l.jsx(se,{field:o,form:c},o.key),e[3]=c,e[4]=n):n=e[4],s=t.map(n),e[0]=t,e[1]=c,e[2]=s}else s=e[2];let a;return e[5]!==s?(a=l.jsx("div",{className:"flex w-full flex-col gap-3",children:s}),e[5]=s,e[6]=a):a=e[6],a},se=({field:i,form:e})=>{const[t,c]=I.useState(!1),s=e.getFieldValue(i.key)??"",[a,n]=I.useState(s),o=!!i.secret;return I.useEffect(()=>{!a&&s&&n(s)},[s]),l.jsxs("div",{className:"grid gap-1.5",children:[l.jsxs(P,{htmlFor:`field-${i.key}`,className:"text-xs",children:[i.label,i.required&&l.jsx("span",{className:"ml-1 text-destructive",children:"*"})]}),l.jsxs("div",{className:"relative",children:[l.jsx(B,{id:`field-${i.key}`,type:o&&!t?"password":"text",value:a,onChange:r=>{const d=r.target.value;n(d),e.setFieldValue(i.key,d)},placeholder:i.placeholder,className:o?"font-mono pr-9":"font-mono"}),o&&l.jsx("button",{type:"button",onClick:()=>c(r=>!r),className:"absolute top-1/2 right-2 -translate-y-1/2 text-muted-foreground hover:text-foreground","aria-label":t?"Hide value":"Show value",children:t?l.jsx(M,{className:"h-4 w-4"}):l.jsx(Q,{className:"h-4 w-4"})})]})]})},le=i=>{const e=O.c(50),{config:t,form:c,connected:s,stored:a,loading:n,error:o,icon:r,onSaveCredentials:d,onLogin:u,onLogout:m,onRefresh:x,extraSection:h}=i,g=!!t.fields?.length;let v;e[0]!==s?(v={label:"Status",ok:()=>s,trueText:"Connected",falseText:"Not Connected"},e[0]=s,e[1]=v):v=e[1];let f;e[2]!==g||e[3]!==a?(f=g?[{label:"Credentials",ok:()=>a,trueText:"Configured",falseText:"Not configured"}]:[],e[2]=g,e[3]=a,e[4]=f):f=e[4];let p;e[5]!==v||e[6]!==f?(p=[v,...f],e[5]=v,e[6]=f,e[7]=p):p=e[7];const E=p,_=`Login with ${t.name}`,U=g&&!a;let b;e[8]!==s||e[9]!==u||e[10]!==_||e[11]!==U?(b={key:"login",label:_,intent:"save",onClick:u,disabled:U,hidden:s},e[8]=s,e[9]=u,e[10]=_,e[11]=U,e[12]=b):b=e[12];const V=!s;let j;e[13]!==m||e[14]!==V?(j={key:"logout",label:"Disconnect",intent:"stop",onClick:m,hidden:V},e[13]=m,e[14]=V,e[15]=j):j=e[15];let R;e[16]===Symbol.for("react.memo_cache_sentinel")?(R=l.jsx(X,{className:"h-4 w-4"}),e[16]=R):R=e[16];let k;e[17]!==x?(k={key:"refresh",label:"Refresh",intent:"save",onClick:x,icon:R},e[17]=x,e[18]=k):k=e[18];let L;e[19]!==k||e[20]!==b||e[21]!==j?(L=[b,j,k],e[19]=k,e[20]=b,e[21]=j,e[22]=L):L=e[22];const q=L,A=n==="save";let N;e[23]!==t.name||e[24]!==r||e[25]!==E?(N=l.jsx(Z,{icon:r,title:t.name,rows:E,status:null}),e[23]=t.name,e[24]=r,e[25]=E,e[26]=N):N=e[26];let S;e[27]!==t.callbackUrl||e[28]!==t.fields||e[29]!==t.instructions||e[30]!==s||e[31]!==c||e[32]!==A||e[33]!==d?(S=!s&&t.fields&&l.jsxs("div",{className:"flex w-full flex-col gap-3",children:[l.jsx(te,{fields:t.fields,form:c}),l.jsxs(D,{intent:"secret",onClick:d,disabled:A,children:[A&&l.jsx(W,{className:"h-4 w-4 animate-spin"}),"Save Credentials"]}),t.instructions&&l.jsxs("div",{className:"text-xs leading-relaxed text-muted-foreground",children:[t.instructions,t.callbackUrl&&l.jsxs(l.Fragment,{children:[l.jsx("br",{}),"Callback URL:"," ",l.jsx("code",{className:"text-accent",children:t.callbackUrl})]})]})]}),e[27]=t.callbackUrl,e[28]=t.fields,e[29]=t.instructions,e[30]=s,e[31]=c,e[32]=A,e[33]=d,e[34]=S):S=e[34];let C;e[35]!==o?(C=o&&l.jsx(H,{variant:"destructive",children:l.jsx(z,{children:o})}),e[35]=o,e[36]=C):C=e[36];const T=s?t.account_label?`Connected as ${t.account_label}.`:`Your ${t.name} account is connected.`:a||!g?"Click Login to authorize.":"Enter your credentials above to get started.";let y;e[37]!==T?(y=l.jsx("div",{className:"rounded-md border border-accent/30 bg-accent/10 p-3",children:l.jsx("div",{className:"text-sm leading-relaxed text-muted-foreground",children:T})}),e[37]=T,e[38]=y):y=e[38];let F;e[39]===Symbol.for("react.memo_cache_sentinel")?(F=l.jsx("div",{className:"flex-1"}),e[39]=F):F=e[39];let w;e[40]!==q||e[41]!==n?(w=l.jsx(J,{actions:q,loading:n}),e[40]=q,e[41]=n,e[42]=w):w=e[42];let $;return e[43]!==h||e[44]!==N||e[45]!==S||e[46]!==C||e[47]!==y||e[48]!==w?($=l.jsxs("div",{className:"flex min-h-0 flex-1 flex-col gap-4",children:[N,S,C,y,h,F,w]}),e[43]=h,e[44]=N,e[45]=S,e[46]=C,e[47]=y,e[48]=w,e[49]=$):$=e[49],$},ge=i=>{const e=O.c(25),{config:t,visible:c}=i,s=G(t,c),a=K(t.statusHook),n=a?!!a.connected:!!t.stored;let o;e[0]!==t.iconRef?(o=l.jsx(Y,{icon:t.iconRef,className:"h-6 w-6 text-2xl"}),e[0]=t.iconRef,e[1]=o):o=e[1];let r;e[2]!==t.fields||e[3]!==s?(r=()=>{const g=t.fields?.find(f=>f.required&&!s.form.getFieldValue(f.key)?.trim());if(g){s.setError(`${g.label} is required`);return}const v=s.form.getFieldsValue();s.execute("save",async()=>{for(const f of t.fields){const p=v[f.key]?.trim();p&&await s.actions.save(f.key,p)}return s.setStored(!0),{success:!0}})},e[2]=t.fields,e[3]=s,e[4]=r):r=e[4];let d,u,m;e[5]!==s.actions?(d=()=>s.actions.oauthLogin(),u=()=>s.actions.oauthLogout(),m=()=>s.actions.oauthRefresh(),e[5]=s.actions,e[6]=d,e[7]=u,e[8]=m):(d=e[6],u=e[7],m=e[8]);let x;e[9]!==t.name||e[10]!==t.usageService?(x=t.usageService&&l.jsx(ee,{service:t.usageService,serviceName:t.name}),e[9]=t.name,e[10]=t.usageService,e[11]=x):x=e[11];let h;return e[12]!==t||e[13]!==n||e[14]!==s.error||e[15]!==s.form||e[16]!==s.loading||e[17]!==s.stored||e[18]!==o||e[19]!==r||e[20]!==d||e[21]!==u||e[22]!==m||e[23]!==x?(h=l.jsx("div",{className:"flex min-h-0 flex-1 flex-col p-5",children:l.jsx(le,{config:t,form:s.form,connected:n,stored:s.stored,loading:s.loading,error:s.error,icon:o,onSaveCredentials:r,onLogin:d,onLogout:u,onRefresh:m,extraSection:x})}),e[12]=t,e[13]=n,e[14]=s.error,e[15]=s.form,e[16]=s.loading,e[17]=s.stored,e[18]=o,e[19]=r,e[20]=d,e[21]=u,e[22]=m,e[23]=x,e[24]=h):h=e[24],h};export{ge as default};
@@ -1 +0,0 @@
1
- import{j as e}from"./vendor-radix-BGeDhy8U.js";import{b as d,R as Q}from"./vendor-react-CxXU_nq3.js";import{d as S,l as k,e as _,m as w,N as A}from"./index-DNx1tG6T.js";import{A as v}from"./ApiKeyInput-DljozMIZ.js";import{Q as E}from"./vendor-misc-4my8ai2A.js";import{aj as W,ac as F,bd as M,ag as b}from"./vendor-icons-BPyNc2rK.js";import{u as T,R as q}from"./RateLimitSection-B2lBVQs0.js";import{u as L,A as D}from"./ActionBar-DAHXJmEU.js";import{S as P}from"./StatusCard-BlufvZD-.js";import"./vendor-flow-apeQB2hf.js";import"./vendor-query-to9T1kjL.js";import"./vendor-markdown-Bx_GU1E7.js";const V=t=>t.length<100?!1:t.startsWith("data:image/")||t.startsWith("iVBOR")||t.startsWith("/9j/")?!0:t.length>5e3?/^[A-Za-z0-9+/=]+$/.test(t):!1,B=({value:t,isConnected:c=!1,size:s=280,loading:a=!1,connectedTitle:u="Connected",connectedSubtitle:x="No QR code needed",emptyText:h="QR code not available"})=>{if(c)return e.jsxs("div",{className:"flex flex-col items-center gap-3 p-8 text-center",children:[e.jsx(W,{className:"h-10 w-10 text-success"}),e.jsx("div",{className:"text-base font-semibold",children:u}),e.jsx("div",{className:"text-sm text-muted-foreground",children:x})]});if(a)return e.jsxs("div",{className:"p-10 text-center",children:[e.jsx(F,{className:"mx-auto h-8 w-8 animate-spin text-muted-foreground"}),e.jsx("div",{className:"mt-4 text-sm text-muted-foreground",children:"Waiting for QR code..."})]});if(!t)return e.jsxs("div",{className:"p-10 text-center text-muted-foreground",children:[e.jsx(M,{className:"mx-auto h-12 w-12 opacity-30"}),e.jsx("div",{className:"mt-4",children:h})]});if(V(t)){const o=t.startsWith("data:")?t:`data:image/png;base64,${t}`;return e.jsx("div",{className:"p-4 text-center",children:e.jsx("img",{src:o,alt:"QR Code",style:{width:s,height:s,imageRendering:"pixelated"}})})}return e.jsx(I,{value:t,size:s})},I=({value:t,size:c})=>{const[s,a]=d.useState(null);return d.useEffect(()=>{a(null)},[t]),s?e.jsx("div",{className:"p-6 text-center",children:e.jsxs(S,{variant:"warning",children:[e.jsx(b,{className:"h-4 w-4"}),e.jsx(k,{children:"QR Code Error"}),e.jsx(_,{children:"The QR code data is too large to display. Please try refreshing or reconnecting."})]})}):e.jsx(G,{onError:u=>a(u),children:e.jsx("div",{className:"p-4 text-center",children:e.jsx(E,{value:t,size:c,level:"L"})})})};class G extends Q.Component{constructor(c){super(c),this.state={hasError:!1}}static getDerivedStateFromError(c){return{hasError:!0}}componentDidCatch(c){console.error("[QRCodeDisplay] QR code rendering error:",c.message),this.props.onError(c.message)}render(){return this.state.hasError?e.jsx("div",{className:"p-6 text-center",children:e.jsxs(S,{variant:"warning",children:[e.jsx(b,{className:"h-4 w-4"}),e.jsx(k,{children:"QR Code Error"}),e.jsx(_,{children:"The QR code data is too large to display. Please try refreshing or reconnecting."})]})}):this.props.children}}const H=()=>{const{getWhatsAppStatus:t,getWhatsAppQR:c,sendWhatsAppMessage:s,startWhatsAppConnection:a,restartWhatsAppConnection:u,isConnected:x}=w(),[h,o]=d.useState(!1),[y,n]=d.useState(null),[p,j]=d.useState(null),m=d.useCallback(async()=>{o(!0),n(null);try{const r=await t();return j(r),r}catch(r){const l=r.message||"Failed to get status";return n(l),{connected:!1}}finally{o(!1)}},[t]),C=d.useCallback(async()=>{o(!0),n(null);try{const r=await c();return r.connected&&j({connected:!0}),r}catch(r){const l=r.message||"Failed to get QR code";return n(l),{connected:!1,message:l}}finally{o(!1)}},[c]),R=d.useCallback(async(r,l)=>{o(!0),n(null);try{const f=await s(r,l);return!f.success&&f.error&&n(f.error),f}catch(f){const N=f.message||"Failed to send message";return n(N),{success:!1,error:N}}finally{o(!1)}},[s]),i=d.useCallback(async()=>{o(!0),n(null);try{const r=await a();return!r.success&&r.message&&n(r.message),r}catch(r){const l=r.message||"Failed to start connection";return n(l),{success:!1,message:l}}finally{o(!1)}},[a]),g=d.useCallback(async()=>{o(!0),n(null);try{const r=await u();return!r.success&&r.message&&n(r.message),r}catch(r){const l=r.message||"Failed to restart connection";return n(l),{success:!1,message:l}}finally{o(!1)}},[u]);return{getStatus:m,getQRCode:C,sendMessage:R,startConnection:i,restartConnection:g,isLoading:h,lastError:y,connectionStatus:p,isConnected:x}},re=({config:t,visible:c})=>{const s=T(t,c),a=L(t.statusHook),{startConnection:u,restartConnection:x,getStatus:h}=H(),{sendRequest:o,setAndroidStatus:y}=w(),n=t.qr,p=n.isConnected(a),j=a?.[n.qrField],m=t.fields?.[0],C=d.useMemo(()=>({start:()=>s.execute("start",u),restart:()=>s.execute("restart",x),refresh:()=>s.execute("refresh",h),connect:()=>s.execute("connect",async()=>{const i=s.form.getFieldValue("android_remote")?.trim();if(!i){s.setError("No API key configured");return}const g=await o("android_relay_connect",{url:"",api_key:i});return g.qr_data&&y(r=>({...r,connected:!0,paired:!1,qr_data:g.qr_data,session_token:g.session_token||r.session_token})),g}),disconnect:()=>s.execute("disconnect",()=>o("android_relay_disconnect",{}))}),[s,u,x,h,o,y]),R=(t.actions??[]).map(i=>({key:i.key,label:i.label,intent:i.intent,onClick:C[i.key]??(()=>{}),hidden:i.hidden?.(a,s.stored),disabled:i.disabled?.(a,s.stored)}));return e.jsxs("div",{className:"flex min-h-0 flex-1 flex-col gap-4 p-5",children:[m&&e.jsx(v,{value:s.form.getFieldValue(m.key)||"",onChange:i=>s.form.setFieldValue(m.key,i),onSave:()=>s.actions.save(m.key,(s.form.getFieldValue(m.key)??"").trim()).then(()=>s.setStored(!0)),onDelete:()=>s.actions.remove(m.key),placeholder:m.placeholder,loading:s.loading==="save",isStored:s.stored}),t.statusRows&&e.jsx(P,{icon:e.jsx(A,{icon:t.iconRef,className:"h-6 w-6 text-2xl"}),title:t.name,rows:t.statusRows,status:a}),e.jsxs("div",{className:"flex min-h-[300px] flex-1 flex-col items-center justify-center rounded-lg bg-muted p-5",children:[e.jsx(B,{value:j,isConnected:p,size:280,connectedTitle:n.connectedTitle,connectedSubtitle:n.connectedSubtitle(a),loading:n.isLoading(a),emptyText:n.emptyText(a,s.stored)}),!p&&j&&e.jsx("div",{className:"mt-3 text-sm text-muted-foreground",children:n.scanText})]}),t.hasRateLimits&&p&&e.jsx(q,{}),s.error&&e.jsx(S,{variant:"destructive",children:e.jsx(_,{children:s.error})}),e.jsx(D,{actions:R,loading:s.loading})]})};export{re as default};
@@ -1 +0,0 @@
1
- import{b as o,h as le}from"./vendor-react-CxXU_nq3.js";import{a as pe,u as je}from"./vendor-query-to9T1kjL.js";import{u as re,m as se,s as G,S as ge,t as oe,v as ie,A as ce,a as de,b as ue,c as me,F as xe,w as _,x as w,y as S,z as J,D as C,E as Y,G as I,H as X,J as O,K as D,M as Q,g as B,I as $,O as Z,B as ee,_ as ne,P as b,Q as H,R as ye,d as _e,e as ve,f as be}from"./index-DNx1tG6T.js";import{j as e}from"./vendor-radix-BGeDhy8U.js";import{ab as we,ac as he}from"./vendor-icons-BPyNc2rK.js";const W={};function Ve(n,l){const x=pe(),[h,j]=o.useState(null),[p,c]=o.useState(null),[F,v]=o.useState(!1);o.useEffect(()=>{c(null),j(null),v(!1)},[n.id]);const{validateApiKey:u,saveApiKey:y,removeApiKey:A,getProviderDefaults:R,saveProviderDefaults:P,getProviderUsageSummary:i,getAPIUsageSummary:a,getStoredModels:d,getModelConstraints:g,isConnected:T}=re(),{sendRequest:k}=se(),E=je({queryKey:G.credentialValues.byProvider(n.id).queryKey,queryFn:async()=>{if(!n.fields)return{values:W,hadStored:!1};const t=await Promise.all(n.fields.map(async K=>{const fe=K.key==="apiKey"?n.id:K.key,ae=await k("get_stored_api_key",{provider:fe});return{key:K.key,hasKey:ae.hasKey,apiKey:ae.apiKey}})),f={};let m=!1;for(const K of t)K.apiKey&&(f[K.key]=K.apiKey),K.hasKey&&(m=!0);return{values:f,hadStored:m}},enabled:l&&T&&!!n.fields,staleTime:ge.FOREVER}),L=E.data?.values??W,M=o.useRef(L);M.current=L;const N=n.id,q=o.useCallback(t=>{x.setQueryData(G.credentialValues.byProvider(N).queryKey,f=>({values:t(f?.values??W),hadStored:f?.hadStored??!1}))},[x,N]),z=o.useMemo(()=>({getFieldValue:t=>M.current[t],getFieldsValue:()=>({...M.current}),setFieldValue:(t,f)=>{q(m=>({...m,[t]:f}))},setFieldsValue:t=>{q(f=>({...f,...t}))},resetFields:()=>q(()=>W)}),[q]);(E.data?.hadStored??!1)&&!F&&v(!0);const r=o.useCallback(async(t,f)=>{j(t),c(null);try{const m=await f();return m&&!m.success&&m.error&&c(m.error),m}catch(m){c(m.message||`Failed: ${t}`);return}finally{j(null)}},[]),V=o.useCallback(()=>x.invalidateQueries({queryKey:G.credentialValues.byProvider(N).queryKey}),[x,N]);return{form:z,values:L,loading:h,error:p,stored:F,setStored:v,setError:c,execute:r,actions:{validate:(t,f)=>r("validate",async()=>{const m=await u(t,f);return m?.isValid&&(v(!0),await V()),m}),save:(t,f)=>r("save",async()=>{const m=await y(t,f);return m?.isValid&&(v(!0),await V()),m}),remove:t=>r("remove",async()=>{await A(t),v(!1),await V()}),oauthLogin:()=>r("login",async()=>{const t=await k(n.ws.login,{});return t.success&&t.url&&window.open(t.url,"_blank"),t}),oauthLogout:()=>r("logout",()=>k(n.ws.logout,{})),oauthRefresh:()=>r("refresh",()=>k(n.ws.status,{})),sendWs:(t,f)=>r(t,()=>k(t,f??{}))},isConnected:T,getProviderDefaults:R,saveProviderDefaults:P,getProviderUsageSummary:i,getAPIUsageSummary:a,getStoredModels:d,getModelConstraints:g}}const Se=ie({default_model:ye().optional().default(""),temperature:b().optional(),max_tokens:b().int().min(1).optional(),thinking_enabled:H().optional().default(!1),thinking_budget:b().int().min(1024).max(16e3).optional(),reasoning_effort:ne(["low","medium","high"]).optional(),reasoning_format:ne(["parsed","hidden"]).optional()}),Ke=({providerId:n})=>{const{getProviderDefaults:l,saveProviderDefaults:x,getStoredModels:h,getModelConstraints:j,isConnected:p}=re(),{apiKeyStatuses:c}=se(),F=c[n],[v,u]=o.useState([]),[y,A]=o.useState(null),[R,P]=o.useState(!1),i=le({resolver:oe(Se),defaultValues:{}}),a=i.watch("default_model"),d=i.watch("thinking_enabled"),{isDirty:g}=i.formState;o.useEffect(()=>{if(!p)return;u([]),A(null);let s=!1;return(async()=>{P(!0);try{const[r,V]=await Promise.all([l(n),h(n)]);s||(i.reset(r??{}),u(V??[]))}finally{s||P(!1)}})(),()=>{s=!0}},[n,p,F]),o.useEffect(()=>{if(!p||!a)return;let s=!1;return j(a,n).then(r=>{s||(A(r),r?.max_output_tokens&&i.getValues("max_tokens")!==r.max_output_tokens&&i.setValue("max_tokens",r.max_output_tokens,{shouldDirty:!1}))}),()=>{s=!0}},[a,n,p]);const T=o.useCallback(async s=>{P(!0);try{await x(n,s)&&i.reset(s)}finally{P(!1)}},[n,x,i]),[k,E]=y?.temperature_range??[0,2],L=y?.max_output_tokens,M=y?.thinking_type,N=y?.supports_thinking,q=y?.is_reasoning_model&&k===E,z=s=>r=>{const V=r.target.value;s.onChange(V===""?void 0:Number(V))};return e.jsx(ce,{type:"single",collapsible:!0,defaultValue:"defaults",children:e.jsxs(de,{value:"defaults",children:[e.jsx(ue,{children:e.jsxs("span",{className:"flex items-center gap-2",children:[e.jsx(we,{className:"h-4 w-4"})," Default Parameters"]})}),e.jsx(me,{children:e.jsx("div",{className:R?"pointer-events-none opacity-60":"",children:e.jsx(xe,{...i,children:e.jsxs("form",{id:`provider-defaults-form-${n}`,onSubmit:i.handleSubmit(T),className:"flex flex-col gap-3",children:[e.jsx(_,{control:i.control,name:"default_model",render:({field:s})=>e.jsxs(w,{children:[e.jsx(S,{children:"Default Model"}),e.jsxs(J,{value:s.value??"",onValueChange:s.onChange,children:[e.jsx(C,{children:e.jsx(Y,{children:e.jsx(I,{placeholder:v.length?"Select model":"Validate API key first"})})}),e.jsx(X,{children:v.map(r=>e.jsx(O,{value:r,children:r},r))})]}),e.jsx(D,{children:"Model used when none specified"}),e.jsx(Q,{})]})}),y&&e.jsxs("div",{className:"flex flex-wrap items-center gap-1.5",children:[L!=null&&e.jsxs(B,{variant:"success",children:["Max Output: ",L.toLocaleString()]}),y.context_length!=null&&e.jsxs(B,{variant:"info",children:["Context: ",y.context_length.toLocaleString()]}),e.jsxs(B,{variant:"secondary",children:["Temp: ",k,"-",E]}),N&&e.jsxs(B,{variant:"warning",children:["Thinking: ",M]}),y.is_reasoning_model&&e.jsx(B,{variant:"outline",children:"Reasoning"})]}),!q&&e.jsx(_,{control:i.control,name:"temperature",render:({field:s})=>e.jsxs(w,{children:[e.jsx(S,{children:"Temperature"}),e.jsx(C,{children:e.jsx($,{type:"number",min:k,max:E,step:.1,className:"w-24",value:s.value??"",onChange:z(s)})}),e.jsxs(D,{children:["Controls randomness (",k,"-",E,")"]}),e.jsx(Q,{})]})}),e.jsx(_,{control:i.control,name:"max_tokens",render:({field:s})=>e.jsxs(w,{children:[e.jsx(S,{children:"Max Tokens"}),e.jsx(C,{children:e.jsx($,{type:"number",min:1,max:L||void 0,className:"w-32",value:s.value??"",onChange:z(s)})}),e.jsx(D,{children:L!=null?`Up to ${L.toLocaleString()}`:"Maximum response length"}),e.jsx(Q,{})]})}),N&&e.jsx(_,{control:i.control,name:"thinking_enabled",render:({field:s})=>e.jsxs(w,{className:"flex flex-row items-center justify-between rounded-md border border-border p-3",children:[e.jsxs("div",{className:"space-y-0.5",children:[e.jsx(S,{children:"Thinking / Reasoning"}),e.jsxs(D,{children:["Extended thinking (",M,")"]})]}),e.jsx(C,{children:e.jsx(Z,{checked:!!s.value,onCheckedChange:s.onChange})})]})}),N&&M==="budget"&&d&&e.jsx(_,{control:i.control,name:"thinking_budget",render:({field:s})=>e.jsxs(w,{children:[e.jsx(S,{children:"Thinking Budget"}),e.jsx(C,{children:e.jsx($,{type:"number",min:1024,max:16e3,className:"w-28",value:s.value??"",onChange:z(s)})}),e.jsx(D,{children:"Token budget (1024-16000)"}),e.jsx(Q,{})]})}),N&&M==="effort"&&d&&e.jsx(_,{control:i.control,name:"reasoning_effort",render:({field:s})=>e.jsxs(w,{children:[e.jsx(S,{children:"Reasoning Effort"}),e.jsxs(J,{value:s.value??"",onValueChange:s.onChange,children:[e.jsx(C,{children:e.jsx(Y,{className:"w-32",children:e.jsx(I,{placeholder:"Select"})})}),e.jsxs(X,{children:[e.jsx(O,{value:"low",children:"Low"}),e.jsx(O,{value:"medium",children:"Medium"}),e.jsx(O,{value:"high",children:"High"})]})]}),e.jsx(D,{children:"Low, medium, or high"}),e.jsx(Q,{})]})}),N&&M==="format"&&d&&e.jsx(_,{control:i.control,name:"reasoning_format",render:({field:s})=>e.jsxs(w,{children:[e.jsx(S,{children:"Reasoning Format"}),e.jsxs(J,{value:s.value??"",onValueChange:s.onChange,children:[e.jsx(C,{children:e.jsx(Y,{className:"w-32",children:e.jsx(I,{placeholder:"Select"})})}),e.jsxs(X,{children:[e.jsx(O,{value:"parsed",children:"Parsed"}),e.jsx(O,{value:"hidden",children:"Hidden"})]})]}),e.jsx(D,{children:"Parsed or hidden"}),e.jsx(Q,{})]})}),e.jsxs(ee,{type:"submit",disabled:!g||R,variant:g?"default":"outline",className:"w-full",children:[R&&e.jsx(he,{className:"h-4 w-4 animate-spin"}),"Save Defaults"]})]})})})})]})})},Ce=ie({enabled:H().default(!1),min_delay_ms:b().int().min(0).optional(),max_delay_ms:b().int().min(0).optional(),typing_delay_ms:b().int().min(0).optional(),link_extra_delay_ms:b().int().min(0).optional(),max_messages_per_minute:b().int().min(0).optional(),max_messages_per_hour:b().int().min(0).optional(),max_new_contacts_per_day:b().int().min(0).optional(),simulate_typing:H().optional(),randomize_delays:H().optional(),pause_on_low_response:H().optional(),response_rate_threshold:b().min(0).max(1).optional()}),U=n=>{const l=be.c(7),{label:x,value:h}=n;let j;l[0]!==x?(j=e.jsx("span",{className:"text-xs text-muted-foreground",children:x}),l[0]=x,l[1]=j):j=l[1];let p;l[2]!==h?(p=e.jsx("span",{className:"text-lg font-semibold",children:h}),l[2]=h,l[3]=p):p=l[3];let c;return l[4]!==j||l[5]!==p?(c=e.jsxs("div",{className:"flex flex-col",children:[j,p]}),l[4]=j,l[5]=p,l[6]=c):c=l[6],c},te=n=>l=>{const x=l.target.value;n.onChange(x===""?void 0:Number(x))},De=()=>{const{getWhatsAppRateLimitConfig:n,setWhatsAppRateLimitConfig:l,unpauseWhatsAppRateLimit:x}=se(),[h,j]=o.useState(null),[p,c]=o.useState(!1),[F,v]=o.useState(!1),u=le({resolver:oe(Ce),defaultValues:{enabled:!1}}),y=u.watch("pause_on_low_response"),{isDirty:A}=u.formState,R=o.useCallback(async()=>{c(!0);try{const a=await n();a.success&&a.config&&(u.reset(a.config),j(a.stats??null),v(!0))}finally{c(!1)}},[u,n]);o.useEffect(()=>{R()},[R]);const P=o.useCallback(async a=>{c(!0);try{const d=await l(a);d.success&&d.config&&u.reset(d.config)}finally{c(!1)}},[u,l]),i=o.useCallback(async()=>{c(!0);try{const a=await x();a.success&&a.stats&&j(a.stats)}finally{c(!1)}},[x]);return e.jsx(ce,{type:"single",collapsible:!0,children:e.jsxs(de,{value:"ratelimits",children:[e.jsx(ue,{children:e.jsxs("div",{className:"flex w-full items-center justify-between gap-2",children:[e.jsx("span",{children:"Rate Limits"}),e.jsx(_,{control:u.control,name:"enabled",render:({field:a})=>e.jsx("span",{onClick:d=>d.stopPropagation(),children:e.jsx(Z,{checked:!!a.value,onCheckedChange:a.onChange})})})]})}),e.jsx(me,{children:F?e.jsx(xe,{...u,children:e.jsxs("form",{onSubmit:u.handleSubmit(P),className:"flex flex-col gap-3",children:[h&&e.jsxs("div",{className:"mb-3 flex flex-wrap gap-4",children:[e.jsx(U,{label:"Last Minute",value:h.messages_sent_last_minute}),e.jsx(U,{label:"Last Hour",value:h.messages_sent_last_hour}),e.jsx(U,{label:"Today",value:h.messages_sent_today}),e.jsx(U,{label:"New Contacts",value:h.new_contacts_today}),e.jsx(U,{label:"Responses",value:h.responses_received}),e.jsx(U,{label:"Response Rate",value:`${Math.round((h.response_rate||0)*100)}%`})]}),h?.is_paused&&e.jsx(_e,{variant:"warning",children:e.jsxs(ve,{className:"flex items-center justify-between gap-3",children:[e.jsx("span",{children:h.pause_reason||"Paused"}),e.jsx(ee,{size:"sm",variant:"outline",type:"button",onClick:i,children:"Unpause"})]})}),e.jsx("div",{className:"text-xs font-medium text-muted-foreground",children:"Message Delays (milliseconds)"}),e.jsx("div",{className:"flex flex-wrap gap-3",children:[["min_delay_ms","Min Delay"],["max_delay_ms","Max Delay"],["typing_delay_ms","Typing Duration"],["link_extra_delay_ms","Link Extra Delay"]].map(([a,d])=>e.jsx(_,{control:u.control,name:a,render:({field:g})=>e.jsxs(w,{children:[e.jsx(S,{className:"text-xs",children:d}),e.jsx(C,{children:e.jsx($,{type:"number",min:0,className:"w-28",value:g.value??"",onChange:te(g)})})]})},a))}),e.jsx("div",{className:"text-xs font-medium text-muted-foreground",children:"Message Limits"}),e.jsx("div",{className:"flex flex-wrap gap-3",children:[["max_messages_per_minute","Per Minute"],["max_messages_per_hour","Per Hour"],["max_new_contacts_per_day","New Contacts/Day"]].map(([a,d])=>e.jsx(_,{control:u.control,name:a,render:({field:g})=>e.jsxs(w,{children:[e.jsx(S,{className:"text-xs",children:d}),e.jsx(C,{children:e.jsx($,{type:"number",min:0,className:"w-32",value:g.value??"",onChange:te(g)})})]})},a))}),e.jsx("div",{className:"text-xs font-medium text-muted-foreground",children:"Behavior"}),e.jsxs("div",{className:"flex w-full flex-col gap-2",children:[[["simulate_typing","Simulate Typing","Show typing indicator before sending"],["randomize_delays","Randomize Delays","Add variance between min/max delay"],["pause_on_low_response","Pause on Low Response","Auto-pause if response rate drops below threshold"]].map(([a,d,g])=>e.jsx(_,{control:u.control,name:a,render:({field:T})=>e.jsxs(w,{className:"flex flex-row items-center justify-between rounded-md border border-border p-3",children:[e.jsxs("div",{className:"space-y-0.5",children:[e.jsx(S,{children:d}),e.jsx(D,{children:g})]}),e.jsx(C,{children:e.jsx(Z,{checked:!!T.value,onCheckedChange:T.onChange})})]})},a)),y&&e.jsx(_,{control:u.control,name:"response_rate_threshold",render:({field:a})=>e.jsxs(w,{children:[e.jsx(S,{children:"Response Rate Threshold (%)"}),e.jsx(C,{children:e.jsx($,{type:"number",min:0,max:100,value:Math.round((a.value??.3)*100),onChange:d=>{const g=d.target.value;a.onChange(g===""?void 0:Number(g)/100)}})})]})})]}),e.jsxs(ee,{type:"submit",disabled:!A||p,variant:A?"default":"outline",className:"w-full",children:[p&&e.jsx(he,{className:"h-4 w-4 animate-spin"}),"Save Changes"]})]})}):e.jsx("div",{className:"flex justify-center p-4 text-sm text-muted-foreground",children:"Loading..."})})]})})};export{Ke as P,De as R,Ve as u};