machinaos 0.0.1 → 0.0.6
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/.env.template +71 -71
- package/LICENSE +21 -21
- package/README.md +145 -87
- package/bin/cli.js +62 -106
- package/client/.dockerignore +45 -45
- package/client/Dockerfile +68 -68
- package/client/dist/assets/index-DFSC53FP.css +1 -0
- package/client/dist/assets/index-fJ-1gTf5.js +613 -0
- package/client/dist/index.html +14 -0
- package/client/eslint.config.js +34 -16
- package/client/nginx.conf +66 -66
- package/client/package.json +61 -48
- package/client/src/App.tsx +27 -27
- package/client/src/Dashboard.tsx +1200 -1172
- package/client/src/ParameterPanel.tsx +302 -300
- package/client/src/components/AIAgentNode.tsx +315 -321
- package/client/src/components/APIKeyValidator.tsx +117 -117
- package/client/src/components/ClaudeChatModelNode.tsx +17 -17
- package/client/src/components/CredentialsModal.tsx +1200 -306
- package/client/src/components/GeminiChatModelNode.tsx +17 -17
- package/client/src/components/GenericNode.tsx +356 -356
- package/client/src/components/LocationParameterPanel.tsx +153 -153
- package/client/src/components/ModelNode.tsx +285 -285
- package/client/src/components/OpenAIChatModelNode.tsx +17 -17
- package/client/src/components/OutputPanel.tsx +470 -470
- package/client/src/components/ParameterRenderer.tsx +1873 -1873
- package/client/src/components/SkillEditorModal.tsx +3 -3
- package/client/src/components/SquareNode.tsx +812 -796
- package/client/src/components/ToolkitNode.tsx +365 -365
- package/client/src/components/auth/LoginPage.tsx +247 -247
- package/client/src/components/auth/ProtectedRoute.tsx +59 -59
- package/client/src/components/base/BaseChatModelNode.tsx +270 -270
- package/client/src/components/icons/AIProviderIcons.tsx +50 -50
- package/client/src/components/maps/GoogleMapsPicker.tsx +136 -136
- package/client/src/components/maps/MapsPreviewPanel.tsx +109 -109
- package/client/src/components/maps/index.ts +25 -25
- package/client/src/components/parameterPanel/InputSection.tsx +1094 -1094
- package/client/src/components/parameterPanel/LocationPanelLayout.tsx +64 -64
- package/client/src/components/parameterPanel/MapsSection.tsx +91 -91
- package/client/src/components/parameterPanel/MiddleSection.tsx +867 -571
- package/client/src/components/parameterPanel/OutputSection.tsx +80 -80
- package/client/src/components/parameterPanel/ParameterPanelLayout.tsx +81 -81
- package/client/src/components/parameterPanel/ToolSchemaEditor.tsx +436 -436
- package/client/src/components/parameterPanel/index.ts +41 -41
- package/client/src/components/shared/DataPanel.tsx +142 -142
- package/client/src/components/shared/JSONTreeRenderer.tsx +105 -105
- package/client/src/components/ui/AIResultModal.tsx +203 -203
- package/client/src/components/ui/ApiKeyInput.tsx +93 -0
- package/client/src/components/ui/CodeEditor.tsx +81 -81
- package/client/src/components/ui/CollapsibleSection.tsx +87 -87
- package/client/src/components/ui/ComponentItem.tsx +153 -153
- package/client/src/components/ui/ComponentPalette.tsx +320 -320
- package/client/src/components/ui/ConsolePanel.tsx +151 -43
- package/client/src/components/ui/ErrorBoundary.tsx +195 -195
- package/client/src/components/ui/InputNodesPanel.tsx +203 -203
- package/client/src/components/ui/MapSelector.tsx +313 -313
- package/client/src/components/ui/Modal.tsx +151 -148
- package/client/src/components/ui/NodeOutputPanel.tsx +1150 -1150
- package/client/src/components/ui/OutputDisplayPanel.tsx +381 -381
- package/client/src/components/ui/QRCodeDisplay.tsx +182 -0
- package/client/src/components/ui/TopToolbar.tsx +736 -736
- package/client/src/components/ui/WorkflowSidebar.tsx +293 -293
- package/client/src/config/antdTheme.ts +186 -186
- package/client/src/contexts/AuthContext.tsx +221 -221
- package/client/src/contexts/ThemeContext.tsx +42 -42
- package/client/src/contexts/WebSocketContext.tsx +2144 -1971
- package/client/src/factories/baseChatModelFactory.ts +255 -255
- package/client/src/hooks/useAndroidOperations.ts +118 -164
- package/client/src/hooks/useApiKeyValidation.ts +106 -106
- package/client/src/hooks/useApiKeys.ts +238 -238
- package/client/src/hooks/useAppTheme.ts +17 -17
- package/client/src/hooks/useComponentPalette.ts +50 -50
- package/client/src/hooks/useDragAndDrop.ts +123 -123
- package/client/src/hooks/useDragVariable.ts +88 -88
- package/client/src/hooks/useExecution.ts +319 -313
- package/client/src/hooks/useParameterPanel.ts +176 -176
- package/client/src/hooks/useReactFlowNodes.ts +188 -188
- package/client/src/hooks/useToolSchema.ts +209 -209
- package/client/src/hooks/useWhatsApp.ts +196 -196
- package/client/src/hooks/useWorkflowManagement.ts +45 -45
- package/client/src/index.css +314 -314
- package/client/src/nodeDefinitions/aiAgentNodes.ts +335 -335
- package/client/src/nodeDefinitions/aiModelNodes.ts +340 -340
- package/client/src/nodeDefinitions/androidServiceNodes.ts +383 -383
- package/client/src/nodeDefinitions/chatNodes.ts +135 -135
- package/client/src/nodeDefinitions/codeNodes.ts +54 -54
- package/client/src/nodeDefinitions/index.ts +14 -14
- package/client/src/nodeDefinitions/locationNodes.ts +462 -462
- package/client/src/nodeDefinitions/schedulerNodes.ts +220 -220
- package/client/src/nodeDefinitions/skillNodes.ts +17 -5
- package/client/src/nodeDefinitions/utilityNodes.ts +284 -284
- package/client/src/nodeDefinitions/whatsappNodes.ts +821 -865
- package/client/src/nodeDefinitions.ts +101 -103
- package/client/src/services/dynamicParameterService.ts +95 -95
- package/client/src/services/execution/aiAgentExecutionService.ts +34 -34
- package/client/src/services/executionService.ts +227 -231
- package/client/src/services/workflowApi.ts +91 -91
- package/client/src/store/useAppStore.ts +578 -581
- package/client/src/styles/theme.ts +513 -508
- package/client/src/styles/zIndex.ts +16 -16
- package/client/src/types/ComponentTypes.ts +38 -38
- package/client/src/types/INodeProperties.ts +287 -287
- package/client/src/types/NodeTypes.ts +27 -27
- package/client/src/utils/formatters.ts +32 -32
- package/client/src/utils/googleMapsLoader.ts +139 -139
- package/client/src/utils/locationUtils.ts +84 -84
- package/client/src/utils/nodeUtils.ts +30 -30
- package/client/src/utils/workflow.ts +29 -29
- package/client/src/vite-env.d.ts +12 -12
- package/client/tailwind.config.js +59 -59
- package/client/tsconfig.json +25 -25
- package/client/vite.config.js +35 -35
- package/package.json +78 -70
- package/scripts/build.js +153 -45
- package/scripts/clean.js +40 -40
- package/scripts/start.js +234 -210
- package/scripts/stop.js +301 -325
- package/server/.dockerignore +44 -44
- package/server/Dockerfile +45 -45
- package/server/constants.py +244 -249
- package/server/core/cache.py +460 -460
- package/server/core/config.py +127 -127
- package/server/core/container.py +98 -98
- package/server/core/database.py +1296 -1210
- package/server/core/logging.py +313 -313
- package/server/main.py +288 -288
- package/server/middleware/__init__.py +5 -5
- package/server/middleware/auth.py +89 -89
- package/server/models/auth.py +52 -52
- package/server/models/cache.py +24 -24
- package/server/models/database.py +235 -210
- package/server/models/nodes.py +435 -455
- package/server/pyproject.toml +75 -72
- package/server/requirements.txt +83 -83
- package/server/routers/android.py +294 -294
- package/server/routers/auth.py +203 -203
- package/server/routers/database.py +150 -150
- package/server/routers/maps.py +141 -141
- package/server/routers/nodejs_compat.py +288 -288
- package/server/routers/webhook.py +90 -90
- package/server/routers/websocket.py +2239 -2127
- package/server/routers/whatsapp.py +761 -761
- package/server/routers/workflow.py +199 -199
- package/server/services/ai.py +2444 -2414
- package/server/services/android_service.py +588 -588
- package/server/services/auth.py +130 -130
- package/server/services/chat_client.py +160 -160
- package/server/services/deployment/manager.py +706 -706
- package/server/services/event_waiter.py +675 -785
- package/server/services/execution/executor.py +1351 -1351
- package/server/services/execution/models.py +1 -1
- package/server/services/handlers/__init__.py +122 -126
- package/server/services/handlers/ai.py +390 -355
- package/server/services/handlers/android.py +69 -260
- package/server/services/handlers/code.py +278 -278
- package/server/services/handlers/http.py +193 -193
- package/server/services/handlers/tools.py +146 -32
- package/server/services/handlers/triggers.py +107 -107
- package/server/services/handlers/utility.py +822 -822
- package/server/services/handlers/whatsapp.py +423 -476
- package/server/services/maps.py +288 -288
- package/server/services/memory_store.py +103 -103
- package/server/services/node_executor.py +372 -375
- package/server/services/scheduler.py +155 -155
- package/server/services/skill_loader.py +1 -1
- package/server/services/status_broadcaster.py +834 -826
- package/server/services/temporal/__init__.py +23 -23
- package/server/services/temporal/activities.py +344 -344
- package/server/services/temporal/client.py +76 -76
- package/server/services/temporal/executor.py +147 -147
- package/server/services/temporal/worker.py +251 -251
- package/server/services/temporal/workflow.py +355 -355
- package/server/services/temporal/ws_client.py +236 -236
- package/server/services/text.py +110 -110
- package/server/services/user_auth.py +172 -172
- package/server/services/websocket_client.py +29 -29
- package/server/services/workflow.py +597 -597
- package/server/skills/android-skill/SKILL.md +4 -4
- package/server/skills/code-skill/SKILL.md +123 -89
- package/server/skills/maps-skill/SKILL.md +3 -3
- package/server/skills/memory-skill/SKILL.md +1 -1
- package/server/skills/web-search-skill/SKILL.md +154 -0
- package/server/skills/whatsapp-skill/SKILL.md +3 -3
- package/server/uv.lock +461 -100
- package/server/whatsapp-rpc/.dockerignore +30 -30
- package/server/whatsapp-rpc/Dockerfile +44 -44
- package/server/whatsapp-rpc/Dockerfile.web +17 -17
- package/server/whatsapp-rpc/README.md +139 -139
- package/server/whatsapp-rpc/bin/whatsapp-rpc-server +0 -0
- package/server/whatsapp-rpc/cli.js +95 -95
- package/server/whatsapp-rpc/configs/config.yaml +6 -6
- package/server/whatsapp-rpc/docker-compose.yml +35 -35
- package/server/whatsapp-rpc/docs/API.md +410 -410
- package/server/whatsapp-rpc/node_modules/.package-lock.json +259 -0
- package/server/whatsapp-rpc/node_modules/chalk/license +9 -0
- package/server/whatsapp-rpc/node_modules/chalk/package.json +83 -0
- package/server/whatsapp-rpc/node_modules/chalk/readme.md +297 -0
- package/server/whatsapp-rpc/node_modules/chalk/source/index.d.ts +325 -0
- package/server/whatsapp-rpc/node_modules/chalk/source/index.js +225 -0
- package/server/whatsapp-rpc/node_modules/chalk/source/utilities.js +33 -0
- package/server/whatsapp-rpc/node_modules/chalk/source/vendor/ansi-styles/index.d.ts +236 -0
- package/server/whatsapp-rpc/node_modules/chalk/source/vendor/ansi-styles/index.js +223 -0
- package/server/whatsapp-rpc/node_modules/chalk/source/vendor/supports-color/browser.d.ts +1 -0
- package/server/whatsapp-rpc/node_modules/chalk/source/vendor/supports-color/browser.js +34 -0
- package/server/whatsapp-rpc/node_modules/chalk/source/vendor/supports-color/index.d.ts +55 -0
- package/server/whatsapp-rpc/node_modules/chalk/source/vendor/supports-color/index.js +190 -0
- package/server/whatsapp-rpc/node_modules/commander/LICENSE +22 -0
- package/server/whatsapp-rpc/node_modules/commander/Readme.md +1148 -0
- package/server/whatsapp-rpc/node_modules/commander/esm.mjs +16 -0
- package/server/whatsapp-rpc/node_modules/commander/index.js +26 -0
- package/server/whatsapp-rpc/node_modules/commander/lib/argument.js +145 -0
- package/server/whatsapp-rpc/node_modules/commander/lib/command.js +2179 -0
- package/server/whatsapp-rpc/node_modules/commander/lib/error.js +43 -0
- package/server/whatsapp-rpc/node_modules/commander/lib/help.js +462 -0
- package/server/whatsapp-rpc/node_modules/commander/lib/option.js +329 -0
- package/server/whatsapp-rpc/node_modules/commander/lib/suggestSimilar.js +100 -0
- package/server/whatsapp-rpc/node_modules/commander/package-support.json +16 -0
- package/server/whatsapp-rpc/node_modules/commander/package.json +80 -0
- package/server/whatsapp-rpc/node_modules/commander/typings/esm.d.mts +3 -0
- package/server/whatsapp-rpc/node_modules/commander/typings/index.d.ts +884 -0
- package/server/whatsapp-rpc/node_modules/cross-spawn/LICENSE +21 -0
- package/server/whatsapp-rpc/node_modules/cross-spawn/README.md +89 -0
- package/server/whatsapp-rpc/node_modules/cross-spawn/index.js +39 -0
- package/server/whatsapp-rpc/node_modules/cross-spawn/lib/enoent.js +59 -0
- package/server/whatsapp-rpc/node_modules/cross-spawn/lib/parse.js +91 -0
- package/server/whatsapp-rpc/node_modules/cross-spawn/lib/util/escape.js +47 -0
- package/server/whatsapp-rpc/node_modules/cross-spawn/lib/util/readShebang.js +23 -0
- package/server/whatsapp-rpc/node_modules/cross-spawn/lib/util/resolveCommand.js +52 -0
- package/server/whatsapp-rpc/node_modules/cross-spawn/package.json +73 -0
- package/server/whatsapp-rpc/node_modules/execa/index.d.ts +955 -0
- package/server/whatsapp-rpc/node_modules/execa/index.js +309 -0
- package/server/whatsapp-rpc/node_modules/execa/lib/command.js +119 -0
- package/server/whatsapp-rpc/node_modules/execa/lib/error.js +87 -0
- package/server/whatsapp-rpc/node_modules/execa/lib/kill.js +102 -0
- package/server/whatsapp-rpc/node_modules/execa/lib/pipe.js +42 -0
- package/server/whatsapp-rpc/node_modules/execa/lib/promise.js +36 -0
- package/server/whatsapp-rpc/node_modules/execa/lib/stdio.js +49 -0
- package/server/whatsapp-rpc/node_modules/execa/lib/stream.js +133 -0
- package/server/whatsapp-rpc/node_modules/execa/lib/verbose.js +19 -0
- package/server/whatsapp-rpc/node_modules/execa/license +9 -0
- package/server/whatsapp-rpc/node_modules/execa/package.json +90 -0
- package/server/whatsapp-rpc/node_modules/execa/readme.md +822 -0
- package/server/whatsapp-rpc/node_modules/get-stream/license +9 -0
- package/server/whatsapp-rpc/node_modules/get-stream/package.json +53 -0
- package/server/whatsapp-rpc/node_modules/get-stream/readme.md +291 -0
- package/server/whatsapp-rpc/node_modules/get-stream/source/array-buffer.js +84 -0
- package/server/whatsapp-rpc/node_modules/get-stream/source/array.js +32 -0
- package/server/whatsapp-rpc/node_modules/get-stream/source/buffer.js +20 -0
- package/server/whatsapp-rpc/node_modules/get-stream/source/contents.js +101 -0
- package/server/whatsapp-rpc/node_modules/get-stream/source/index.d.ts +119 -0
- package/server/whatsapp-rpc/node_modules/get-stream/source/index.js +5 -0
- package/server/whatsapp-rpc/node_modules/get-stream/source/string.js +36 -0
- package/server/whatsapp-rpc/node_modules/get-stream/source/utils.js +11 -0
- package/server/whatsapp-rpc/node_modules/get-them-args/LICENSE +21 -0
- package/server/whatsapp-rpc/node_modules/get-them-args/README.md +95 -0
- package/server/whatsapp-rpc/node_modules/get-them-args/index.js +97 -0
- package/server/whatsapp-rpc/node_modules/get-them-args/package.json +36 -0
- package/server/whatsapp-rpc/node_modules/human-signals/LICENSE +201 -0
- package/server/whatsapp-rpc/node_modules/human-signals/README.md +168 -0
- package/server/whatsapp-rpc/node_modules/human-signals/build/src/core.js +273 -0
- package/server/whatsapp-rpc/node_modules/human-signals/build/src/main.d.ts +73 -0
- package/server/whatsapp-rpc/node_modules/human-signals/build/src/main.js +70 -0
- package/server/whatsapp-rpc/node_modules/human-signals/build/src/realtime.js +16 -0
- package/server/whatsapp-rpc/node_modules/human-signals/build/src/signals.js +34 -0
- package/server/whatsapp-rpc/node_modules/human-signals/package.json +61 -0
- package/server/whatsapp-rpc/node_modules/is-stream/index.d.ts +81 -0
- package/server/whatsapp-rpc/node_modules/is-stream/index.js +29 -0
- package/server/whatsapp-rpc/node_modules/is-stream/license +9 -0
- package/server/whatsapp-rpc/node_modules/is-stream/package.json +44 -0
- package/server/whatsapp-rpc/node_modules/is-stream/readme.md +60 -0
- package/server/whatsapp-rpc/node_modules/isexe/LICENSE +15 -0
- package/server/whatsapp-rpc/node_modules/isexe/README.md +51 -0
- package/server/whatsapp-rpc/node_modules/isexe/index.js +57 -0
- package/server/whatsapp-rpc/node_modules/isexe/mode.js +41 -0
- package/server/whatsapp-rpc/node_modules/isexe/package.json +31 -0
- package/server/whatsapp-rpc/node_modules/isexe/test/basic.js +221 -0
- package/server/whatsapp-rpc/node_modules/isexe/windows.js +42 -0
- package/server/whatsapp-rpc/node_modules/kill-port/.editorconfig +12 -0
- package/server/whatsapp-rpc/node_modules/kill-port/.gitattributes +1 -0
- package/server/whatsapp-rpc/node_modules/kill-port/LICENSE +21 -0
- package/server/whatsapp-rpc/node_modules/kill-port/README.md +140 -0
- package/server/whatsapp-rpc/node_modules/kill-port/cli.js +25 -0
- package/server/whatsapp-rpc/node_modules/kill-port/example.js +21 -0
- package/server/whatsapp-rpc/node_modules/kill-port/index.js +46 -0
- package/server/whatsapp-rpc/node_modules/kill-port/logo.png +0 -0
- package/server/whatsapp-rpc/node_modules/kill-port/package.json +41 -0
- package/server/whatsapp-rpc/node_modules/kill-port/pnpm-lock.yaml +4606 -0
- package/server/whatsapp-rpc/node_modules/kill-port/test.js +16 -0
- package/server/whatsapp-rpc/node_modules/merge-stream/LICENSE +21 -0
- package/server/whatsapp-rpc/node_modules/merge-stream/README.md +78 -0
- package/server/whatsapp-rpc/node_modules/merge-stream/index.js +41 -0
- package/server/whatsapp-rpc/node_modules/merge-stream/package.json +19 -0
- package/server/whatsapp-rpc/node_modules/mimic-fn/index.d.ts +52 -0
- package/server/whatsapp-rpc/node_modules/mimic-fn/index.js +71 -0
- package/server/whatsapp-rpc/node_modules/mimic-fn/license +9 -0
- package/server/whatsapp-rpc/node_modules/mimic-fn/package.json +45 -0
- package/server/whatsapp-rpc/node_modules/mimic-fn/readme.md +90 -0
- package/server/whatsapp-rpc/node_modules/npm-run-path/index.d.ts +90 -0
- package/server/whatsapp-rpc/node_modules/npm-run-path/index.js +52 -0
- package/server/whatsapp-rpc/node_modules/npm-run-path/license +9 -0
- package/server/whatsapp-rpc/node_modules/npm-run-path/node_modules/path-key/index.d.ts +31 -0
- package/server/whatsapp-rpc/node_modules/npm-run-path/node_modules/path-key/index.js +12 -0
- package/server/whatsapp-rpc/node_modules/npm-run-path/node_modules/path-key/license +9 -0
- package/server/whatsapp-rpc/node_modules/npm-run-path/node_modules/path-key/package.json +41 -0
- package/server/whatsapp-rpc/node_modules/npm-run-path/node_modules/path-key/readme.md +57 -0
- package/server/whatsapp-rpc/node_modules/npm-run-path/package.json +49 -0
- package/server/whatsapp-rpc/node_modules/npm-run-path/readme.md +104 -0
- package/server/whatsapp-rpc/node_modules/onetime/index.d.ts +59 -0
- package/server/whatsapp-rpc/node_modules/onetime/index.js +41 -0
- package/server/whatsapp-rpc/node_modules/onetime/license +9 -0
- package/server/whatsapp-rpc/node_modules/onetime/package.json +45 -0
- package/server/whatsapp-rpc/node_modules/onetime/readme.md +94 -0
- package/server/whatsapp-rpc/node_modules/path-key/index.d.ts +40 -0
- package/server/whatsapp-rpc/node_modules/path-key/index.js +16 -0
- package/server/whatsapp-rpc/node_modules/path-key/license +9 -0
- package/server/whatsapp-rpc/node_modules/path-key/package.json +39 -0
- package/server/whatsapp-rpc/node_modules/path-key/readme.md +61 -0
- package/server/whatsapp-rpc/node_modules/shebang-command/index.js +19 -0
- package/server/whatsapp-rpc/node_modules/shebang-command/license +9 -0
- package/server/whatsapp-rpc/node_modules/shebang-command/package.json +34 -0
- package/server/whatsapp-rpc/node_modules/shebang-command/readme.md +34 -0
- package/server/whatsapp-rpc/node_modules/shebang-regex/index.d.ts +22 -0
- package/server/whatsapp-rpc/node_modules/shebang-regex/index.js +2 -0
- package/server/whatsapp-rpc/node_modules/shebang-regex/license +9 -0
- package/server/whatsapp-rpc/node_modules/shebang-regex/package.json +35 -0
- package/server/whatsapp-rpc/node_modules/shebang-regex/readme.md +33 -0
- package/server/whatsapp-rpc/node_modules/shell-exec/LICENSE +21 -0
- package/server/whatsapp-rpc/node_modules/shell-exec/README.md +60 -0
- package/server/whatsapp-rpc/node_modules/shell-exec/index.js +47 -0
- package/server/whatsapp-rpc/node_modules/shell-exec/package.json +29 -0
- package/server/whatsapp-rpc/node_modules/signal-exit/LICENSE.txt +16 -0
- package/server/whatsapp-rpc/node_modules/signal-exit/README.md +74 -0
- package/server/whatsapp-rpc/node_modules/signal-exit/dist/cjs/browser.d.ts +12 -0
- package/server/whatsapp-rpc/node_modules/signal-exit/dist/cjs/browser.d.ts.map +1 -0
- package/server/whatsapp-rpc/node_modules/signal-exit/dist/cjs/browser.js +10 -0
- package/server/whatsapp-rpc/node_modules/signal-exit/dist/cjs/browser.js.map +1 -0
- package/server/whatsapp-rpc/node_modules/signal-exit/dist/cjs/index.d.ts +48 -0
- package/server/whatsapp-rpc/node_modules/signal-exit/dist/cjs/index.d.ts.map +1 -0
- package/server/whatsapp-rpc/node_modules/signal-exit/dist/cjs/index.js +279 -0
- package/server/whatsapp-rpc/node_modules/signal-exit/dist/cjs/index.js.map +1 -0
- package/server/whatsapp-rpc/node_modules/signal-exit/dist/cjs/package.json +3 -0
- package/server/whatsapp-rpc/node_modules/signal-exit/dist/cjs/signals.d.ts +29 -0
- package/server/whatsapp-rpc/node_modules/signal-exit/dist/cjs/signals.d.ts.map +1 -0
- package/server/whatsapp-rpc/node_modules/signal-exit/dist/cjs/signals.js +42 -0
- package/server/whatsapp-rpc/node_modules/signal-exit/dist/cjs/signals.js.map +1 -0
- package/server/whatsapp-rpc/node_modules/signal-exit/dist/mjs/browser.d.ts +12 -0
- package/server/whatsapp-rpc/node_modules/signal-exit/dist/mjs/browser.d.ts.map +1 -0
- package/server/whatsapp-rpc/node_modules/signal-exit/dist/mjs/browser.js +4 -0
- package/server/whatsapp-rpc/node_modules/signal-exit/dist/mjs/browser.js.map +1 -0
- package/server/whatsapp-rpc/node_modules/signal-exit/dist/mjs/index.d.ts +48 -0
- package/server/whatsapp-rpc/node_modules/signal-exit/dist/mjs/index.d.ts.map +1 -0
- package/server/whatsapp-rpc/node_modules/signal-exit/dist/mjs/index.js +275 -0
- package/server/whatsapp-rpc/node_modules/signal-exit/dist/mjs/index.js.map +1 -0
- package/server/whatsapp-rpc/node_modules/signal-exit/dist/mjs/package.json +3 -0
- package/server/whatsapp-rpc/node_modules/signal-exit/dist/mjs/signals.d.ts +29 -0
- package/server/whatsapp-rpc/node_modules/signal-exit/dist/mjs/signals.d.ts.map +1 -0
- package/server/whatsapp-rpc/node_modules/signal-exit/dist/mjs/signals.js +39 -0
- package/server/whatsapp-rpc/node_modules/signal-exit/dist/mjs/signals.js.map +1 -0
- package/server/whatsapp-rpc/node_modules/signal-exit/package.json +106 -0
- package/server/whatsapp-rpc/node_modules/strip-final-newline/index.js +14 -0
- package/server/whatsapp-rpc/node_modules/strip-final-newline/license +9 -0
- package/server/whatsapp-rpc/node_modules/strip-final-newline/package.json +43 -0
- package/server/whatsapp-rpc/node_modules/strip-final-newline/readme.md +35 -0
- package/server/whatsapp-rpc/node_modules/which/CHANGELOG.md +166 -0
- package/server/whatsapp-rpc/node_modules/which/LICENSE +15 -0
- package/server/whatsapp-rpc/node_modules/which/README.md +54 -0
- package/server/whatsapp-rpc/node_modules/which/bin/node-which +52 -0
- package/server/whatsapp-rpc/node_modules/which/package.json +43 -0
- package/server/whatsapp-rpc/node_modules/which/which.js +125 -0
- package/server/whatsapp-rpc/package-lock.json +272 -0
- package/server/whatsapp-rpc/package.json +30 -30
- package/server/whatsapp-rpc/schema.json +1294 -1294
- package/server/whatsapp-rpc/scripts/clean.cjs +66 -66
- package/server/whatsapp-rpc/scripts/cli.js +162 -162
- package/server/whatsapp-rpc/src/go/whatsapp/history.go +166 -166
- package/server/whatsapp-rpc/src/python/pyproject.toml +15 -15
- package/server/whatsapp-rpc/src/python/whatsapp_rpc/__init__.py +4 -4
- package/server/whatsapp-rpc/src/python/whatsapp_rpc/client.py +427 -427
- package/server/whatsapp-rpc/web/app.py +609 -609
- package/server/whatsapp-rpc/web/requirements.txt +6 -6
- package/server/whatsapp-rpc/web/rpc_client.py +427 -427
- package/server/whatsapp-rpc/web/static/openapi.yaml +59 -59
- package/server/whatsapp-rpc/web/templates/base.html +149 -149
- package/server/whatsapp-rpc/web/templates/contacts.html +240 -240
- package/server/whatsapp-rpc/web/templates/dashboard.html +319 -319
- package/server/whatsapp-rpc/web/templates/groups.html +328 -328
- package/server/whatsapp-rpc/web/templates/messages.html +465 -465
- package/server/whatsapp-rpc/web/templates/messaging.html +680 -680
- package/server/whatsapp-rpc/web/templates/send.html +258 -258
- package/server/whatsapp-rpc/web/templates/settings.html +459 -459
- package/client/src/components/ui/AndroidSettingsPanel.tsx +0 -401
- package/client/src/components/ui/WhatsAppSettingsPanel.tsx +0 -345
- package/client/src/nodeDefinitions/androidDeviceNodes.ts +0 -140
- package/docker-compose.prod.yml +0 -107
- package/docker-compose.yml +0 -104
- package/docs-MachinaOs/README.md +0 -85
- package/docs-MachinaOs/deployment/docker.mdx +0 -228
- package/docs-MachinaOs/deployment/production.mdx +0 -345
- package/docs-MachinaOs/docs.json +0 -75
- package/docs-MachinaOs/faq.mdx +0 -309
- package/docs-MachinaOs/favicon.svg +0 -5
- package/docs-MachinaOs/installation.mdx +0 -160
- package/docs-MachinaOs/introduction.mdx +0 -114
- package/docs-MachinaOs/logo/dark.svg +0 -6
- package/docs-MachinaOs/logo/light.svg +0 -6
- package/docs-MachinaOs/nodes/ai-agent.mdx +0 -216
- package/docs-MachinaOs/nodes/ai-models.mdx +0 -240
- package/docs-MachinaOs/nodes/android.mdx +0 -411
- package/docs-MachinaOs/nodes/overview.mdx +0 -181
- package/docs-MachinaOs/nodes/schedulers.mdx +0 -316
- package/docs-MachinaOs/nodes/webhooks.mdx +0 -330
- package/docs-MachinaOs/nodes/whatsapp.mdx +0 -305
- package/docs-MachinaOs/quickstart.mdx +0 -119
- package/docs-MachinaOs/tutorials/ai-agent-workflow.mdx +0 -177
- package/docs-MachinaOs/tutorials/android-automation.mdx +0 -242
- package/docs-MachinaOs/tutorials/first-workflow.mdx +0 -134
- package/docs-MachinaOs/tutorials/whatsapp-automation.mdx +0 -185
- package/nul +0 -0
- package/scripts/check-ports.ps1 +0 -33
- package/scripts/kill-port.ps1 +0 -154
package/server/services/auth.py
CHANGED
|
@@ -1,131 +1,131 @@
|
|
|
1
|
-
"""Simple API key management service."""
|
|
2
|
-
|
|
3
|
-
import hashlib
|
|
4
|
-
import base64
|
|
5
|
-
from datetime import datetime, timedelta, timezone
|
|
6
|
-
from typing import Dict, Any, Optional, List
|
|
7
|
-
|
|
8
|
-
from core.config import Settings
|
|
9
|
-
from core.database import Database
|
|
10
|
-
from core.cache import CacheService
|
|
11
|
-
from core.logging import get_logger
|
|
12
|
-
|
|
13
|
-
logger = get_logger(__name__)
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
class AuthService:
|
|
17
|
-
"""Simple API key management service."""
|
|
18
|
-
|
|
19
|
-
def __init__(self, database: Database, cache: CacheService, settings: Settings):
|
|
20
|
-
self.database = database
|
|
21
|
-
self.cache = cache
|
|
22
|
-
self.settings = settings
|
|
23
|
-
|
|
24
|
-
def encrypt_api_key(self, api_key: str) -> str:
|
|
25
|
-
"""Simple base64 encoding (compatible with frontend)."""
|
|
26
|
-
return base64.b64encode(api_key.encode()).decode()
|
|
27
|
-
|
|
28
|
-
def decrypt_api_key(self, encrypted_key: str) -> str:
|
|
29
|
-
"""Simple base64 decoding."""
|
|
30
|
-
try:
|
|
31
|
-
return base64.b64decode(encrypted_key.encode()).decode()
|
|
32
|
-
except Exception:
|
|
33
|
-
return ""
|
|
34
|
-
|
|
35
|
-
def hash_api_key(self, api_key: str) -> str:
|
|
36
|
-
"""Create hash for API key identification."""
|
|
37
|
-
return hashlib.sha256(api_key.encode()).hexdigest()[:16]
|
|
38
|
-
|
|
39
|
-
async def store_api_key(self, provider: str, api_key: str, models: List[str],
|
|
40
|
-
session_id: str = "default") -> bool:
|
|
41
|
-
"""Store API key with models."""
|
|
42
|
-
try:
|
|
43
|
-
key_id = f"{session_id}_{provider}"
|
|
44
|
-
encrypted_key = self.encrypt_api_key(api_key)
|
|
45
|
-
key_hash = self.hash_api_key(api_key)
|
|
46
|
-
|
|
47
|
-
logger.info(f"Storing API key for provider: {provider}, session: {session_id}, key_id: {key_id}")
|
|
48
|
-
|
|
49
|
-
# Store in database
|
|
50
|
-
success = await self.database.save_api_key(
|
|
51
|
-
key_id=key_id,
|
|
52
|
-
provider=provider,
|
|
53
|
-
session_id=session_id,
|
|
54
|
-
key_encrypted=encrypted_key,
|
|
55
|
-
key_hash=key_hash,
|
|
56
|
-
models=models
|
|
57
|
-
)
|
|
58
|
-
|
|
59
|
-
logger.info(f"Database save result: {success}")
|
|
60
|
-
|
|
61
|
-
# Cache for quick access
|
|
62
|
-
if success:
|
|
63
|
-
cache_data = {
|
|
64
|
-
"encrypted_key": encrypted_key,
|
|
65
|
-
"models": models,
|
|
66
|
-
"last_validated": datetime.utcnow().isoformat()
|
|
67
|
-
}
|
|
68
|
-
await self.cache.cache_api_key(provider, session_id, cache_data)
|
|
69
|
-
logger.info(f"Cached API key for {provider}")
|
|
70
|
-
|
|
71
|
-
return success
|
|
72
|
-
|
|
73
|
-
except Exception as e:
|
|
74
|
-
logger.error("Failed to store API key", provider=provider, error=str(e))
|
|
75
|
-
return False
|
|
76
|
-
|
|
77
|
-
async def get_api_key(self, provider: str, session_id: str = "default") -> Optional[str]:
|
|
78
|
-
"""Get decrypted API key."""
|
|
79
|
-
try:
|
|
80
|
-
# Try cache first
|
|
81
|
-
cached_data = await self.cache.get_cached_api_key(provider, session_id)
|
|
82
|
-
if cached_data:
|
|
83
|
-
return self.decrypt_api_key(cached_data["encrypted_key"])
|
|
84
|
-
|
|
85
|
-
# Fallback to database
|
|
86
|
-
api_key_record = await self.database.get_api_key_by_provider(provider, session_id)
|
|
87
|
-
if api_key_record and api_key_record.is_valid:
|
|
88
|
-
# Check if not expired (30 days)
|
|
89
|
-
if datetime.now(timezone.utc) - api_key_record.last_validated < timedelta(days=30):
|
|
90
|
-
return self.decrypt_api_key(api_key_record.key_encrypted)
|
|
91
|
-
|
|
92
|
-
return None
|
|
93
|
-
|
|
94
|
-
except Exception as e:
|
|
95
|
-
logger.error("Failed to get API key", provider=provider, error=str(e))
|
|
96
|
-
return None
|
|
97
|
-
|
|
98
|
-
async def get_stored_models(self, provider: str, session_id: str = "default") -> List[str]:
|
|
99
|
-
"""Get stored models for provider."""
|
|
100
|
-
try:
|
|
101
|
-
# Try cache first
|
|
102
|
-
cached_data = await self.cache.get_cached_api_key(provider, session_id)
|
|
103
|
-
if cached_data and cached_data.get("models"):
|
|
104
|
-
return cached_data["models"]
|
|
105
|
-
|
|
106
|
-
# Fallback to database
|
|
107
|
-
api_key_record = await self.database.get_api_key_by_provider(provider, session_id)
|
|
108
|
-
if api_key_record and api_key_record.models:
|
|
109
|
-
return api_key_record.models.get("models", [])
|
|
110
|
-
|
|
111
|
-
return []
|
|
112
|
-
|
|
113
|
-
except Exception as e:
|
|
114
|
-
logger.error("Failed to get stored models", provider=provider, error=str(e))
|
|
115
|
-
return []
|
|
116
|
-
|
|
117
|
-
async def remove_api_key(self, provider: str, session_id: str = "default") -> bool:
|
|
118
|
-
"""Remove API key."""
|
|
119
|
-
try:
|
|
120
|
-
# Remove from cache and database
|
|
121
|
-
await self.cache.remove_cached_api_key(provider, session_id)
|
|
122
|
-
return await self.database.delete_api_key(provider, session_id)
|
|
123
|
-
|
|
124
|
-
except Exception as e:
|
|
125
|
-
logger.error("Failed to remove API key", provider=provider, error=str(e))
|
|
126
|
-
return False
|
|
127
|
-
|
|
128
|
-
async def has_valid_key(self, provider: str, session_id: str = "default") -> bool:
|
|
129
|
-
"""Check if valid API key exists."""
|
|
130
|
-
api_key = await self.get_api_key(provider, session_id)
|
|
1
|
+
"""Simple API key management service."""
|
|
2
|
+
|
|
3
|
+
import hashlib
|
|
4
|
+
import base64
|
|
5
|
+
from datetime import datetime, timedelta, timezone
|
|
6
|
+
from typing import Dict, Any, Optional, List
|
|
7
|
+
|
|
8
|
+
from core.config import Settings
|
|
9
|
+
from core.database import Database
|
|
10
|
+
from core.cache import CacheService
|
|
11
|
+
from core.logging import get_logger
|
|
12
|
+
|
|
13
|
+
logger = get_logger(__name__)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class AuthService:
|
|
17
|
+
"""Simple API key management service."""
|
|
18
|
+
|
|
19
|
+
def __init__(self, database: Database, cache: CacheService, settings: Settings):
|
|
20
|
+
self.database = database
|
|
21
|
+
self.cache = cache
|
|
22
|
+
self.settings = settings
|
|
23
|
+
|
|
24
|
+
def encrypt_api_key(self, api_key: str) -> str:
|
|
25
|
+
"""Simple base64 encoding (compatible with frontend)."""
|
|
26
|
+
return base64.b64encode(api_key.encode()).decode()
|
|
27
|
+
|
|
28
|
+
def decrypt_api_key(self, encrypted_key: str) -> str:
|
|
29
|
+
"""Simple base64 decoding."""
|
|
30
|
+
try:
|
|
31
|
+
return base64.b64decode(encrypted_key.encode()).decode()
|
|
32
|
+
except Exception:
|
|
33
|
+
return ""
|
|
34
|
+
|
|
35
|
+
def hash_api_key(self, api_key: str) -> str:
|
|
36
|
+
"""Create hash for API key identification."""
|
|
37
|
+
return hashlib.sha256(api_key.encode()).hexdigest()[:16]
|
|
38
|
+
|
|
39
|
+
async def store_api_key(self, provider: str, api_key: str, models: List[str],
|
|
40
|
+
session_id: str = "default") -> bool:
|
|
41
|
+
"""Store API key with models."""
|
|
42
|
+
try:
|
|
43
|
+
key_id = f"{session_id}_{provider}"
|
|
44
|
+
encrypted_key = self.encrypt_api_key(api_key)
|
|
45
|
+
key_hash = self.hash_api_key(api_key)
|
|
46
|
+
|
|
47
|
+
logger.info(f"Storing API key for provider: {provider}, session: {session_id}, key_id: {key_id}")
|
|
48
|
+
|
|
49
|
+
# Store in database
|
|
50
|
+
success = await self.database.save_api_key(
|
|
51
|
+
key_id=key_id,
|
|
52
|
+
provider=provider,
|
|
53
|
+
session_id=session_id,
|
|
54
|
+
key_encrypted=encrypted_key,
|
|
55
|
+
key_hash=key_hash,
|
|
56
|
+
models=models
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
logger.info(f"Database save result: {success}")
|
|
60
|
+
|
|
61
|
+
# Cache for quick access
|
|
62
|
+
if success:
|
|
63
|
+
cache_data = {
|
|
64
|
+
"encrypted_key": encrypted_key,
|
|
65
|
+
"models": models,
|
|
66
|
+
"last_validated": datetime.utcnow().isoformat()
|
|
67
|
+
}
|
|
68
|
+
await self.cache.cache_api_key(provider, session_id, cache_data)
|
|
69
|
+
logger.info(f"Cached API key for {provider}")
|
|
70
|
+
|
|
71
|
+
return success
|
|
72
|
+
|
|
73
|
+
except Exception as e:
|
|
74
|
+
logger.error("Failed to store API key", provider=provider, error=str(e))
|
|
75
|
+
return False
|
|
76
|
+
|
|
77
|
+
async def get_api_key(self, provider: str, session_id: str = "default") -> Optional[str]:
|
|
78
|
+
"""Get decrypted API key."""
|
|
79
|
+
try:
|
|
80
|
+
# Try cache first
|
|
81
|
+
cached_data = await self.cache.get_cached_api_key(provider, session_id)
|
|
82
|
+
if cached_data:
|
|
83
|
+
return self.decrypt_api_key(cached_data["encrypted_key"])
|
|
84
|
+
|
|
85
|
+
# Fallback to database
|
|
86
|
+
api_key_record = await self.database.get_api_key_by_provider(provider, session_id)
|
|
87
|
+
if api_key_record and api_key_record.is_valid:
|
|
88
|
+
# Check if not expired (30 days)
|
|
89
|
+
if datetime.now(timezone.utc) - api_key_record.last_validated < timedelta(days=30):
|
|
90
|
+
return self.decrypt_api_key(api_key_record.key_encrypted)
|
|
91
|
+
|
|
92
|
+
return None
|
|
93
|
+
|
|
94
|
+
except Exception as e:
|
|
95
|
+
logger.error("Failed to get API key", provider=provider, error=str(e))
|
|
96
|
+
return None
|
|
97
|
+
|
|
98
|
+
async def get_stored_models(self, provider: str, session_id: str = "default") -> List[str]:
|
|
99
|
+
"""Get stored models for provider."""
|
|
100
|
+
try:
|
|
101
|
+
# Try cache first
|
|
102
|
+
cached_data = await self.cache.get_cached_api_key(provider, session_id)
|
|
103
|
+
if cached_data and cached_data.get("models"):
|
|
104
|
+
return cached_data["models"]
|
|
105
|
+
|
|
106
|
+
# Fallback to database
|
|
107
|
+
api_key_record = await self.database.get_api_key_by_provider(provider, session_id)
|
|
108
|
+
if api_key_record and api_key_record.models:
|
|
109
|
+
return api_key_record.models.get("models", [])
|
|
110
|
+
|
|
111
|
+
return []
|
|
112
|
+
|
|
113
|
+
except Exception as e:
|
|
114
|
+
logger.error("Failed to get stored models", provider=provider, error=str(e))
|
|
115
|
+
return []
|
|
116
|
+
|
|
117
|
+
async def remove_api_key(self, provider: str, session_id: str = "default") -> bool:
|
|
118
|
+
"""Remove API key."""
|
|
119
|
+
try:
|
|
120
|
+
# Remove from cache and database
|
|
121
|
+
await self.cache.remove_cached_api_key(provider, session_id)
|
|
122
|
+
return await self.database.delete_api_key(provider, session_id)
|
|
123
|
+
|
|
124
|
+
except Exception as e:
|
|
125
|
+
logger.error("Failed to remove API key", provider=provider, error=str(e))
|
|
126
|
+
return False
|
|
127
|
+
|
|
128
|
+
async def has_valid_key(self, provider: str, session_id: str = "default") -> bool:
|
|
129
|
+
"""Check if valid API key exists."""
|
|
130
|
+
api_key = await self.get_api_key(provider, session_id)
|
|
131
131
|
return api_key is not None
|
|
@@ -1,160 +1,160 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Chat WebSocket Client - JSON-RPC 2.0 Protocol
|
|
3
|
-
|
|
4
|
-
Simple client for chat backend. Uses aiohttp (already in project).
|
|
5
|
-
Connection URL: ws://{host}:{port}/ws/{sessionId}?api_key={apiKey}&client_type=web
|
|
6
|
-
"""
|
|
7
|
-
|
|
8
|
-
import asyncio
|
|
9
|
-
import json
|
|
10
|
-
import uuid
|
|
11
|
-
import aiohttp
|
|
12
|
-
from typing import Optional, Dict, Any
|
|
13
|
-
import structlog
|
|
14
|
-
|
|
15
|
-
logger = structlog.get_logger()
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
async def send_chat_message(
|
|
19
|
-
host: str,
|
|
20
|
-
port: int,
|
|
21
|
-
session_id: str,
|
|
22
|
-
api_key: str,
|
|
23
|
-
content: str,
|
|
24
|
-
metadata: Optional[Dict[str, Any]] = None,
|
|
25
|
-
timeout: float = 10.0
|
|
26
|
-
) -> Dict[str, Any]:
|
|
27
|
-
"""Send a chat message via JSON-RPC 2.0 WebSocket.
|
|
28
|
-
|
|
29
|
-
Args:
|
|
30
|
-
host: Chat server host
|
|
31
|
-
port: Chat server port
|
|
32
|
-
session_id: Session identifier
|
|
33
|
-
api_key: API key for authentication
|
|
34
|
-
content: Message content
|
|
35
|
-
metadata: Optional message metadata
|
|
36
|
-
timeout: Request timeout in seconds
|
|
37
|
-
|
|
38
|
-
Returns:
|
|
39
|
-
JSON-RPC result or error dict
|
|
40
|
-
"""
|
|
41
|
-
url = f"ws://{host}:{port}/ws/{session_id}?api_key={api_key}&client_type=web"
|
|
42
|
-
request_id = str(uuid.uuid4())
|
|
43
|
-
|
|
44
|
-
request = {
|
|
45
|
-
"jsonrpc": "2.0",
|
|
46
|
-
"method": "chat.sendMessage",
|
|
47
|
-
"params": {"content": content, **(metadata or {})},
|
|
48
|
-
"id": request_id
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
try:
|
|
52
|
-
async with aiohttp.ClientSession() as session:
|
|
53
|
-
async with session.ws_connect(url, timeout=timeout) as ws:
|
|
54
|
-
await ws.send_json(request)
|
|
55
|
-
|
|
56
|
-
# Wait for response with matching id
|
|
57
|
-
async with asyncio.timeout(timeout):
|
|
58
|
-
async for msg in ws:
|
|
59
|
-
if msg.type == aiohttp.WSMsgType.TEXT:
|
|
60
|
-
data = json.loads(msg.data)
|
|
61
|
-
if data.get("id") == request_id:
|
|
62
|
-
if "error" in data:
|
|
63
|
-
return {"success": False, "error": data["error"].get("message", "Unknown error")}
|
|
64
|
-
return {"success": True, "result": data.get("result", {})}
|
|
65
|
-
elif msg.type in (aiohttp.WSMsgType.CLOSED, aiohttp.WSMsgType.ERROR):
|
|
66
|
-
break
|
|
67
|
-
|
|
68
|
-
return {"success": False, "error": "No response received"}
|
|
69
|
-
|
|
70
|
-
except asyncio.TimeoutError:
|
|
71
|
-
return {"success": False, "error": "Connection timeout"}
|
|
72
|
-
except Exception as e:
|
|
73
|
-
logger.error("[Chat] Send error", error=str(e))
|
|
74
|
-
return {"success": False, "error": str(e)}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
async def get_chat_history(
|
|
78
|
-
host: str,
|
|
79
|
-
port: int,
|
|
80
|
-
session_id: str,
|
|
81
|
-
api_key: str,
|
|
82
|
-
limit: int = 50,
|
|
83
|
-
timeout: float = 10.0
|
|
84
|
-
) -> Dict[str, Any]:
|
|
85
|
-
"""Get chat history via JSON-RPC 2.0 WebSocket.
|
|
86
|
-
|
|
87
|
-
Args:
|
|
88
|
-
host: Chat server host
|
|
89
|
-
port: Chat server port
|
|
90
|
-
session_id: Session identifier
|
|
91
|
-
api_key: API key for authentication
|
|
92
|
-
limit: Max messages to return
|
|
93
|
-
timeout: Request timeout in seconds
|
|
94
|
-
|
|
95
|
-
Returns:
|
|
96
|
-
JSON-RPC result with messages or error dict
|
|
97
|
-
"""
|
|
98
|
-
url = f"ws://{host}:{port}/ws/{session_id}?api_key={api_key}&client_type=web"
|
|
99
|
-
request_id = str(uuid.uuid4())
|
|
100
|
-
|
|
101
|
-
request = {
|
|
102
|
-
"jsonrpc": "2.0",
|
|
103
|
-
"method": "chat.getHistory",
|
|
104
|
-
"params": {"limit": limit},
|
|
105
|
-
"id": request_id
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
try:
|
|
109
|
-
async with aiohttp.ClientSession() as session:
|
|
110
|
-
async with session.ws_connect(url, timeout=timeout) as ws:
|
|
111
|
-
await ws.send_json(request)
|
|
112
|
-
|
|
113
|
-
async with asyncio.timeout(timeout):
|
|
114
|
-
async for msg in ws:
|
|
115
|
-
if msg.type == aiohttp.WSMsgType.TEXT:
|
|
116
|
-
data = json.loads(msg.data)
|
|
117
|
-
if data.get("id") == request_id:
|
|
118
|
-
if "error" in data:
|
|
119
|
-
return {"success": False, "error": data["error"].get("message", "Unknown error")}
|
|
120
|
-
return {"success": True, "messages": data.get("result", {}).get("messages", [])}
|
|
121
|
-
elif msg.type in (aiohttp.WSMsgType.CLOSED, aiohttp.WSMsgType.ERROR):
|
|
122
|
-
break
|
|
123
|
-
|
|
124
|
-
return {"success": False, "error": "No response received"}
|
|
125
|
-
|
|
126
|
-
except asyncio.TimeoutError:
|
|
127
|
-
return {"success": False, "error": "Connection timeout"}
|
|
128
|
-
except Exception as e:
|
|
129
|
-
logger.error("[Chat] History error", error=str(e))
|
|
130
|
-
return {"success": False, "error": str(e)}
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
async def ping_chat_server(
|
|
134
|
-
host: str,
|
|
135
|
-
port: int,
|
|
136
|
-
session_id: str,
|
|
137
|
-
api_key: str,
|
|
138
|
-
timeout: float = 5.0
|
|
139
|
-
) -> bool:
|
|
140
|
-
"""Ping chat server to check connectivity."""
|
|
141
|
-
url = f"ws://{host}:{port}/ws/{session_id}?api_key={api_key}&client_type=web"
|
|
142
|
-
request_id = str(uuid.uuid4())
|
|
143
|
-
|
|
144
|
-
try:
|
|
145
|
-
async with aiohttp.ClientSession() as session:
|
|
146
|
-
async with session.ws_connect(url, timeout=timeout) as ws:
|
|
147
|
-
await ws.send_json({"jsonrpc": "2.0", "method": "ping", "params": {}, "id": request_id})
|
|
148
|
-
|
|
149
|
-
async with asyncio.timeout(timeout):
|
|
150
|
-
async for msg in ws:
|
|
151
|
-
if msg.type == aiohttp.WSMsgType.TEXT:
|
|
152
|
-
data = json.loads(msg.data)
|
|
153
|
-
if data.get("id") == request_id:
|
|
154
|
-
return "error" not in data
|
|
155
|
-
elif msg.type in (aiohttp.WSMsgType.CLOSED, aiohttp.WSMsgType.ERROR):
|
|
156
|
-
break
|
|
157
|
-
return False
|
|
158
|
-
|
|
159
|
-
except Exception:
|
|
160
|
-
return False
|
|
1
|
+
"""
|
|
2
|
+
Chat WebSocket Client - JSON-RPC 2.0 Protocol
|
|
3
|
+
|
|
4
|
+
Simple client for chat backend. Uses aiohttp (already in project).
|
|
5
|
+
Connection URL: ws://{host}:{port}/ws/{sessionId}?api_key={apiKey}&client_type=web
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import asyncio
|
|
9
|
+
import json
|
|
10
|
+
import uuid
|
|
11
|
+
import aiohttp
|
|
12
|
+
from typing import Optional, Dict, Any
|
|
13
|
+
import structlog
|
|
14
|
+
|
|
15
|
+
logger = structlog.get_logger()
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
async def send_chat_message(
|
|
19
|
+
host: str,
|
|
20
|
+
port: int,
|
|
21
|
+
session_id: str,
|
|
22
|
+
api_key: str,
|
|
23
|
+
content: str,
|
|
24
|
+
metadata: Optional[Dict[str, Any]] = None,
|
|
25
|
+
timeout: float = 10.0
|
|
26
|
+
) -> Dict[str, Any]:
|
|
27
|
+
"""Send a chat message via JSON-RPC 2.0 WebSocket.
|
|
28
|
+
|
|
29
|
+
Args:
|
|
30
|
+
host: Chat server host
|
|
31
|
+
port: Chat server port
|
|
32
|
+
session_id: Session identifier
|
|
33
|
+
api_key: API key for authentication
|
|
34
|
+
content: Message content
|
|
35
|
+
metadata: Optional message metadata
|
|
36
|
+
timeout: Request timeout in seconds
|
|
37
|
+
|
|
38
|
+
Returns:
|
|
39
|
+
JSON-RPC result or error dict
|
|
40
|
+
"""
|
|
41
|
+
url = f"ws://{host}:{port}/ws/{session_id}?api_key={api_key}&client_type=web"
|
|
42
|
+
request_id = str(uuid.uuid4())
|
|
43
|
+
|
|
44
|
+
request = {
|
|
45
|
+
"jsonrpc": "2.0",
|
|
46
|
+
"method": "chat.sendMessage",
|
|
47
|
+
"params": {"content": content, **(metadata or {})},
|
|
48
|
+
"id": request_id
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
try:
|
|
52
|
+
async with aiohttp.ClientSession() as session:
|
|
53
|
+
async with session.ws_connect(url, timeout=timeout) as ws:
|
|
54
|
+
await ws.send_json(request)
|
|
55
|
+
|
|
56
|
+
# Wait for response with matching id
|
|
57
|
+
async with asyncio.timeout(timeout):
|
|
58
|
+
async for msg in ws:
|
|
59
|
+
if msg.type == aiohttp.WSMsgType.TEXT:
|
|
60
|
+
data = json.loads(msg.data)
|
|
61
|
+
if data.get("id") == request_id:
|
|
62
|
+
if "error" in data:
|
|
63
|
+
return {"success": False, "error": data["error"].get("message", "Unknown error")}
|
|
64
|
+
return {"success": True, "result": data.get("result", {})}
|
|
65
|
+
elif msg.type in (aiohttp.WSMsgType.CLOSED, aiohttp.WSMsgType.ERROR):
|
|
66
|
+
break
|
|
67
|
+
|
|
68
|
+
return {"success": False, "error": "No response received"}
|
|
69
|
+
|
|
70
|
+
except asyncio.TimeoutError:
|
|
71
|
+
return {"success": False, "error": "Connection timeout"}
|
|
72
|
+
except Exception as e:
|
|
73
|
+
logger.error("[Chat] Send error", error=str(e))
|
|
74
|
+
return {"success": False, "error": str(e)}
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
async def get_chat_history(
|
|
78
|
+
host: str,
|
|
79
|
+
port: int,
|
|
80
|
+
session_id: str,
|
|
81
|
+
api_key: str,
|
|
82
|
+
limit: int = 50,
|
|
83
|
+
timeout: float = 10.0
|
|
84
|
+
) -> Dict[str, Any]:
|
|
85
|
+
"""Get chat history via JSON-RPC 2.0 WebSocket.
|
|
86
|
+
|
|
87
|
+
Args:
|
|
88
|
+
host: Chat server host
|
|
89
|
+
port: Chat server port
|
|
90
|
+
session_id: Session identifier
|
|
91
|
+
api_key: API key for authentication
|
|
92
|
+
limit: Max messages to return
|
|
93
|
+
timeout: Request timeout in seconds
|
|
94
|
+
|
|
95
|
+
Returns:
|
|
96
|
+
JSON-RPC result with messages or error dict
|
|
97
|
+
"""
|
|
98
|
+
url = f"ws://{host}:{port}/ws/{session_id}?api_key={api_key}&client_type=web"
|
|
99
|
+
request_id = str(uuid.uuid4())
|
|
100
|
+
|
|
101
|
+
request = {
|
|
102
|
+
"jsonrpc": "2.0",
|
|
103
|
+
"method": "chat.getHistory",
|
|
104
|
+
"params": {"limit": limit},
|
|
105
|
+
"id": request_id
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
try:
|
|
109
|
+
async with aiohttp.ClientSession() as session:
|
|
110
|
+
async with session.ws_connect(url, timeout=timeout) as ws:
|
|
111
|
+
await ws.send_json(request)
|
|
112
|
+
|
|
113
|
+
async with asyncio.timeout(timeout):
|
|
114
|
+
async for msg in ws:
|
|
115
|
+
if msg.type == aiohttp.WSMsgType.TEXT:
|
|
116
|
+
data = json.loads(msg.data)
|
|
117
|
+
if data.get("id") == request_id:
|
|
118
|
+
if "error" in data:
|
|
119
|
+
return {"success": False, "error": data["error"].get("message", "Unknown error")}
|
|
120
|
+
return {"success": True, "messages": data.get("result", {}).get("messages", [])}
|
|
121
|
+
elif msg.type in (aiohttp.WSMsgType.CLOSED, aiohttp.WSMsgType.ERROR):
|
|
122
|
+
break
|
|
123
|
+
|
|
124
|
+
return {"success": False, "error": "No response received"}
|
|
125
|
+
|
|
126
|
+
except asyncio.TimeoutError:
|
|
127
|
+
return {"success": False, "error": "Connection timeout"}
|
|
128
|
+
except Exception as e:
|
|
129
|
+
logger.error("[Chat] History error", error=str(e))
|
|
130
|
+
return {"success": False, "error": str(e)}
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
async def ping_chat_server(
|
|
134
|
+
host: str,
|
|
135
|
+
port: int,
|
|
136
|
+
session_id: str,
|
|
137
|
+
api_key: str,
|
|
138
|
+
timeout: float = 5.0
|
|
139
|
+
) -> bool:
|
|
140
|
+
"""Ping chat server to check connectivity."""
|
|
141
|
+
url = f"ws://{host}:{port}/ws/{session_id}?api_key={api_key}&client_type=web"
|
|
142
|
+
request_id = str(uuid.uuid4())
|
|
143
|
+
|
|
144
|
+
try:
|
|
145
|
+
async with aiohttp.ClientSession() as session:
|
|
146
|
+
async with session.ws_connect(url, timeout=timeout) as ws:
|
|
147
|
+
await ws.send_json({"jsonrpc": "2.0", "method": "ping", "params": {}, "id": request_id})
|
|
148
|
+
|
|
149
|
+
async with asyncio.timeout(timeout):
|
|
150
|
+
async for msg in ws:
|
|
151
|
+
if msg.type == aiohttp.WSMsgType.TEXT:
|
|
152
|
+
data = json.loads(msg.data)
|
|
153
|
+
if data.get("id") == request_id:
|
|
154
|
+
return "error" not in data
|
|
155
|
+
elif msg.type in (aiohttp.WSMsgType.CLOSED, aiohttp.WSMsgType.ERROR):
|
|
156
|
+
break
|
|
157
|
+
return False
|
|
158
|
+
|
|
159
|
+
except Exception:
|
|
160
|
+
return False
|