nyxora 26.7.4 → 26.7.8
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/CHANGELOG.md +64 -0
- package/README.md +43 -8
- package/dist/launcher.js +67 -9
- package/dist/packages/core/src/agent/bridgeWatcher.js +1 -1
- package/dist/packages/core/src/agent/cronManager.js +1 -1
- package/dist/packages/core/src/agent/llmProvider.js +78 -7
- package/dist/packages/core/src/agent/nyxDaemon.js +2 -2
- package/dist/packages/core/src/agent/osAgent.js +172 -206
- package/dist/packages/core/src/agent/promptBuilder.js +452 -0
- package/dist/packages/core/src/agent/reasoning.js +155 -208
- package/dist/packages/core/src/agent/reasoningScratchpad.js +19 -2
- package/dist/packages/core/src/agent/threatPatterns.js +106 -0
- package/dist/packages/core/src/agent/web3Agent.js +81 -115
- package/dist/packages/core/src/agent/workspaceUtils.js +56 -0
- package/dist/packages/core/src/channels/ChannelManager.js +36 -0
- package/dist/packages/core/src/channels/discordAdapter.js +81 -0
- package/dist/packages/core/src/channels/googlechatAdapter.js +45 -0
- package/dist/packages/core/src/channels/imessageAdapter.js +34 -0
- package/dist/packages/core/src/channels/index.js +89 -0
- package/dist/packages/core/src/channels/ircAdapter.js +34 -0
- package/dist/packages/core/src/channels/lineAdapter.js +133 -0
- package/dist/packages/core/src/channels/matrixAdapter.js +34 -0
- package/dist/packages/core/src/channels/mattermostAdapter.js +45 -0
- package/dist/packages/core/src/channels/msteamsAdapter.js +45 -0
- package/dist/packages/core/src/channels/nextcloudtalkAdapter.js +45 -0
- package/dist/packages/core/src/channels/nostrAdapter.js +34 -0
- package/dist/packages/core/src/channels/qqbotAdapter.js +34 -0
- package/dist/packages/core/src/channels/slackAdapter.js +116 -0
- package/dist/packages/core/src/channels/smsAdapter.js +45 -0
- package/dist/packages/core/src/channels/synologychatAdapter.js +45 -0
- package/dist/packages/core/src/channels/telegram.js +593 -0
- package/dist/packages/core/src/channels/twitchAdapter.js +34 -0
- package/dist/packages/core/src/channels/voicecallAdapter.js +45 -0
- package/dist/packages/core/src/channels/whatsappAdapter.js +136 -0
- package/dist/packages/core/src/channels/zaloAdapter.js +45 -0
- package/dist/packages/core/src/config/parser.js +2 -1
- package/dist/packages/core/src/gateway/chat.js +10 -2
- package/dist/packages/core/src/gateway/cli.js +4 -1
- package/dist/packages/core/src/gateway/doctor.js +56 -22
- package/dist/packages/core/src/gateway/googleAuthModule.js +111 -13
- package/dist/packages/core/src/gateway/server.js +139 -3
- package/dist/packages/core/src/gateway/setup-ml.js +65 -2
- package/dist/packages/core/src/gateway/setup.js +61 -22
- package/dist/packages/core/src/gateway/telegram.js +21 -48
- package/dist/packages/core/src/memory/episodic.js +4 -0
- package/dist/packages/core/src/memory/logger.js +27 -9
- package/dist/packages/core/src/plugin/PluginManager.js +46 -16
- package/dist/packages/core/src/system/plugins/GoogleWorkspacePlugin.js +69 -30
- package/dist/packages/core/src/system/plugins/SystemNotesPlugin.js +148 -0
- package/dist/packages/core/src/system/plugins/SystemSocialPlugin.js +2 -14
- package/dist/packages/core/src/system/plugins/SystemWebPlugin.js +0 -5
- package/dist/packages/core/src/system/plugins/SystemWorkspacePlugin.js +25 -6
- package/dist/packages/core/src/system/skills/analyzeImage.js +82 -0
- package/dist/packages/core/src/system/skills/fileDownloader.js +45 -0
- package/dist/packages/core/src/system/skills/generateExcel.js +1 -1
- package/dist/packages/core/src/system/skills/googleWorkspace.js +278 -271
- package/dist/packages/core/src/system/skills/playbookManager.js +269 -0
- package/dist/packages/core/src/system/skills/telegramUpload.js +25 -0
- package/dist/packages/core/src/utils/fileLinker.js +57 -0
- package/dist/packages/core/src/utils/historySanitizer.js +19 -5
- package/dist/packages/core/src/utils/llmUtils.js +5 -4
- package/dist/packages/core/src/utils/skillManager.js +12 -4
- package/dist/packages/core/src/utils/streamSimulator.js +40 -40
- package/dist/packages/core/src/web3/skills/checkPortfolio.js +7 -1
- package/dist/packages/core/src/web3/skills/getTxHistory.js +44 -7
- package/dist/packages/core/src/web3/utils/vaultClient.js +20 -22
- package/dist/packages/policy/src/server.js +38 -51
- package/dist/packages/signer/src/server.js +32 -15
- package/launcher.ts +61 -9
- package/package.json +7 -7
- package/packages/core/package.json +27 -9
- package/packages/core/src/agent/bridgeWatcher.ts +1 -1
- package/packages/core/src/agent/cronManager.ts +1 -1
- package/packages/core/src/agent/llmProvider.ts +87 -7
- package/packages/core/src/agent/nyxDaemon.ts +3 -3
- package/packages/core/src/agent/osAgent.ts +180 -209
- package/packages/core/src/agent/promptBuilder.ts +476 -0
- package/packages/core/src/agent/reasoning.ts +156 -213
- package/packages/core/src/agent/reasoningScratchpad.ts +21 -2
- package/packages/core/src/agent/threatPatterns.ts +115 -0
- package/packages/core/src/agent/web3Agent.ts +77 -115
- package/packages/core/src/agent/workspaceUtils.ts +53 -0
- package/packages/core/src/channels/ChannelManager.ts +45 -0
- package/packages/core/src/channels/googlechatAdapter.ts +48 -0
- package/packages/core/src/channels/imessageAdapter.ts +37 -0
- package/packages/core/src/channels/index.ts +57 -0
- package/packages/core/src/channels/ircAdapter.ts +37 -0
- package/packages/core/src/channels/lineAdapter.ts +111 -0
- package/packages/core/src/channels/matrixAdapter.ts +37 -0
- package/packages/core/src/channels/mattermostAdapter.ts +48 -0
- package/packages/core/src/channels/msteamsAdapter.ts +48 -0
- package/packages/core/src/channels/nextcloudtalkAdapter.ts +48 -0
- package/packages/core/src/channels/nostrAdapter.ts +37 -0
- package/packages/core/src/channels/qqbotAdapter.ts +37 -0
- package/packages/core/src/channels/slackAdapter.ts +92 -0
- package/packages/core/src/channels/smsAdapter.ts +48 -0
- package/packages/core/src/channels/synologychatAdapter.ts +48 -0
- package/packages/core/src/channels/telegram.ts +643 -0
- package/packages/core/src/channels/twitchAdapter.ts +37 -0
- package/packages/core/src/channels/voicecallAdapter.ts +48 -0
- package/packages/core/src/channels/whatsappAdapter.ts +113 -0
- package/packages/core/src/channels/zaloAdapter.ts +48 -0
- package/packages/core/src/config/parser.ts +7 -1
- package/packages/core/src/gateway/chat.ts +10 -2
- package/packages/core/src/gateway/cli.ts +4 -1
- package/packages/core/src/gateway/doctor.ts +56 -22
- package/packages/core/src/gateway/googleAuthModule.ts +113 -11
- package/packages/core/src/gateway/server.ts +146 -3
- package/packages/core/src/gateway/setup-ml.ts +65 -4
- package/packages/core/src/gateway/setup.ts +60 -22
- package/packages/core/src/memory/episodic.ts +4 -0
- package/packages/core/src/memory/logger.ts +26 -9
- package/packages/core/src/plugin/PluginManager.ts +78 -16
- package/packages/core/src/system/plugins/GoogleWorkspacePlugin.ts +36 -45
- package/packages/core/src/system/plugins/SystemNotesPlugin.ts +141 -0
- package/packages/core/src/system/plugins/SystemSocialPlugin.ts +2 -14
- package/packages/core/src/system/plugins/SystemWebPlugin.ts +0 -5
- package/packages/core/src/system/plugins/SystemWorkspacePlugin.ts +25 -6
- package/packages/core/src/system/skills/analyzeImage.ts +79 -0
- package/packages/core/src/system/skills/fileDownloader.ts +43 -0
- package/packages/core/src/system/skills/generateExcel.ts +1 -1
- package/packages/core/src/system/skills/googleWorkspace.ts +262 -283
- package/packages/core/src/system/skills/playbookManager.ts +285 -0
- package/packages/core/src/system/skills/telegramUpload.ts +23 -0
- package/packages/core/src/utils/fileLinker.ts +48 -0
- package/packages/core/src/utils/historySanitizer.ts +21 -5
- package/packages/core/src/utils/llmUtils.ts +5 -4
- package/packages/core/src/utils/skillManager.ts +14 -4
- package/packages/core/src/utils/streamSimulator.ts +46 -44
- package/packages/core/src/web3/skills/checkPortfolio.ts +8 -1
- package/packages/core/src/web3/skills/getTxHistory.ts +42 -8
- package/packages/core/src/web3/utils/vaultClient.ts +23 -22
- package/packages/dashboard/dist/assets/index-Dg9eiK4h.css +1 -0
- package/packages/dashboard/dist/assets/index-Dq64NWt0.js +26 -0
- package/packages/dashboard/dist/index.html +2 -2
- package/packages/dashboard/package.json +1 -1
- package/packages/mcp-server/package.json +1 -1
- package/packages/ml-engine/__pycache__/main.cpython-313.pyc +0 -0
- package/packages/ml-engine/main.py +4 -1
- package/packages/ml-engine/routers/__pycache__/background_review.cpython-313.pyc +0 -0
- package/packages/ml-engine/routers/__pycache__/llm.cpython-313.pyc +0 -0
- package/packages/ml-engine/routers/__pycache__/memory_writer.cpython-313.pyc +0 -0
- package/packages/ml-engine/routers/__pycache__/skill_manager.cpython-313.pyc +0 -0
- package/packages/ml-engine/routers/background_review.py +121 -0
- package/packages/ml-engine/routers/llm.py +15 -1
- package/packages/ml-engine/routers/memory_writer.py +72 -0
- package/packages/ml-engine/routers/skill_manager.py +123 -0
- package/packages/policy/package.json +1 -1
- package/packages/policy/src/server.ts +43 -49
- package/packages/signer/package.json +1 -1
- package/packages/signer/src/server.ts +32 -13
- package/packages/core/src/gateway/telegram.ts +0 -357
- package/packages/core/src/system/skills/analyzeDocument.ts +0 -117
- package/packages/core/src/system/skills/gitManager.ts +0 -84
- package/packages/core/src/system/skills/notionWorkspace.ts +0 -78
- package/packages/core/src/system/skills/xManager.ts +0 -76
- package/packages/dashboard/dist/assets/index-Czxksiao.js +0 -18
- package/packages/dashboard/dist/assets/index-DK2sTU47.css +0 -1
- /package/packages/core/src/{gateway → channels}/discordAdapter.ts +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,70 @@ All notable changes to this project will be documented in this file.
|
|
|
4
4
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepashangelog.com/en/1.0.0/),
|
|
6
6
|
|
|
7
|
+
## [26.7.8]
|
|
8
|
+
### Bug Fixes — Global Compatibility & Dashboard Crash
|
|
9
|
+
|
|
10
|
+
- **Dashboard Not Accessible via `nyxora dashboard` (Critical Fix)**: Resolved a crash-on-startup bug where the entire Core gateway process would exit with code `1` before binding to port 3000, making `http://localhost:3000` unreachable. Root cause: `channels/index.ts` performed static top-level imports of `baileys`, `@slack/bolt`, and `@line/bot-sdk` — packages that are **not listed in `package.json` dependencies** and therefore not installed on global npm users' machines. Resolved by refactoring `channels/index.ts` into a `registerAllAdapters()` async function that uses dynamic `import()` with `MODULE_NOT_FOUND` error handling. Missing adapters now log a clear warning and are skipped instead of crashing the process.
|
|
11
|
+
- **WhatsApp Adapter Lazy Load**: Migrated `whatsappAdapter.ts` from a static `import makeWASocket from 'baileys'` to a lazy `await import('baileys')` inside `start()`, with a graceful error and install instructions if `baileys` is absent.
|
|
12
|
+
- **Slack Adapter Lazy Load**: Migrated `slackAdapter.ts` `@slack/bolt` import to lazy initialization inside `start()`.
|
|
13
|
+
- **LINE Adapter Lazy Load**: Migrated `lineAdapter.ts` `@line/bot-sdk` import to lazy initialization inside `start()`.
|
|
14
|
+
|
|
15
|
+
### Bug Fixes — Windows & Cross-Platform Compatibility
|
|
16
|
+
|
|
17
|
+
- **Unix Socket Crash on Windows** (`ENOENT`/`ENOTSUP`): Replaced hardcoded Unix Domain Socket (`/tmp/nyxora-signer.sock`) in `signer/server.ts` with a cross-platform IPC strategy. On Windows, the signer now listens on TCP `127.0.0.1:3002`; Unix/Mac keeps the existing UDS path for security.
|
|
18
|
+
- **Policy Engine Cross-Platform IPC**: Refactored all Signer proxy calls in `policy/server.ts` into a unified `signerRequestOptions()` helper that automatically selects Unix socket (Linux/Mac) or TCP (Windows). The optional UDS IPC server is now skipped entirely on Windows.
|
|
19
|
+
- **vaultClient TCP Fallback**: Refactored `vaultClient.ts` with a `getPolicyOptions()` helper — on Windows, all Policy Engine requests use TCP; on Linux/Mac, Unix socket is preferred if available with automatic TCP fallback.
|
|
20
|
+
- **Python Path on Windows**: Launcher now resolves the ML Engine Python executable to `venv/Scripts/python.exe` on Windows instead of `venv/bin/python`, preventing silent "Python not found" at startup.
|
|
21
|
+
- **`pkill` Skipped on Windows**: Graceful shutdown in `launcher.ts` now guards `pkill -f ts-node` and `pkill -f uvicorn` behind a `process.platform !== 'win32'` check.
|
|
22
|
+
- **Unix Socket Doctor Checks Skipped on Windows**: `nyxora doctor` now conditionally skips UDS socket health checks on Windows where they are not applicable.
|
|
23
|
+
|
|
24
|
+
### Improvements — Configuration & Telemetry
|
|
25
|
+
|
|
26
|
+
- **Cloudflare Tunnel Configurable**: Cloudflare auto-tunnel can now be disabled by setting `cloudflare_tunnel: false` in `~/.nyxora/config/config.yaml`. Previously it always launched unconditionally.
|
|
27
|
+
- **ML Engine Health Check in `nyxora doctor`**: Added a dedicated check (#7) that pings `http://127.0.0.1:8000/health` to detect if the Python ML Engine sidecar is running. When daemon is stopped, it verifies the venv is installed and guides with `nyxora setup`.
|
|
28
|
+
- **Node.js Version Enforcement**: Added `"engines": { "node": ">=22.0.0" }` to `package.json`. npm will now warn users attempting to install on incompatible Node.js versions instead of silently installing and crashing at runtime.
|
|
29
|
+
- **Locale-Neutral System Prompt**: Replaced Indonesian-specific examples (`"cek saldo gue dirupiahin"`, `"fiat/rupiah"`) in `promptBuilder.ts` with multilingual examples (`"0.5 BTC in EUR"`, `"convert 100 SOL to JPY"`) to align with global user base.
|
|
30
|
+
- **English-Only Source Code**: Translated the remaining Indonesian comment in `nyxDaemon.ts` (`// Kirim riwayat percakapan...`) to English for open-source contributor clarity.
|
|
31
|
+
|
|
32
|
+
## [26.7.6]
|
|
33
|
+
### Features & Architecture
|
|
34
|
+
- **ML Engine Custom Provider Support**: Fixed a `500 Internal Server Error` in the Python ML Engine by explicitly supporting the `custom` and `openrouter` providers and gracefully handling empty API keys with a local fallback, ensuring robust execution for cognitive reasoning and RAG memory tasks.
|
|
35
|
+
|
|
36
|
+
### Bug Fixes & Dashboard
|
|
37
|
+
- **Dashboard Overview Key Detection**: Resolved a UI bug in the Dashboard Overview where custom and proxy providers (`custom_provider_key`, `9router_key`) incorrectly rendered as "Missing Key". The status engine now dynamically queries the exact credential mapping for off-standard providers.
|
|
38
|
+
- **LLM Configuration Persistence Bug**: Fixed a configuration merging flaw in `Settings.tsx` where switching away from a `custom_provider` left the old `base_url` intact in the persistent payload. This previously caused subsequent standard LLM providers (e.g., OpenAI) to silently inherit the custom URL and crash. The dashboard now cleanly purges the `base_url` state upon provider transitions.
|
|
39
|
+
|
|
40
|
+
## [26.7.5]
|
|
41
|
+
### Reasoning & Agent Engine Architecture
|
|
42
|
+
- **Event-Driven Tool Execution**: Fully refactored the core agent loop (`osAgent.ts`) from a linear synchronous executor to a highly scalable, event-driven architecture using Lifecycle Hooks (`beforeToolCall`, `afterToolCall`). This completely decouples security guardrails and domain-specific logic from the core loop.
|
|
43
|
+
- **Parallel Execution Concurrency**: Supercharged the agent's data gathering capabilities by upgrading the execution engine to support parallel processing (`Promise.all`), allowing multiple safe tools to run concurrently for massive speed improvements.
|
|
44
|
+
- **Deferred Tool Resolution (MCP Ready)**: Built-in support for dynamic tool resolution, allowing the agent to request and execute external tools (e.g., via Model Context Protocol servers) on-the-fly even if they aren't loaded in the initial context.
|
|
45
|
+
- **Partial Streaming Feedback**: Long-running tools can now stream partial updates (`"⏳ Processing..."`) to the user interface (Telegram/Dashboard) before the execution is fully complete, significantly enhancing UX and transparency.
|
|
46
|
+
- **Advanced Guardrails**: The strict `Reasoning Gate` and `Web3 Fast Return` logic have been cleanly migrated into standalone middleware hooks, ensuring the main executor remains agnostic and maintainable.
|
|
47
|
+
- **Dynamic Reasoning Mapper**: Injected seamless support for `reasoning_effort` across the entire Unified Mapper API, making it universally compatible with both OpenAI and OpenRouter native reasoning models.
|
|
48
|
+
- **UX Sanitizer**: Implemented intelligent regex filtering to intercept and strip raw LLM `<think>` tags before they are broadcast to user-facing channels, keeping chat interfaces clean and elegant.
|
|
49
|
+
|
|
50
|
+
### UI/UX & Design System Overhaul
|
|
51
|
+
- **Modern UI Aesthetic**: Executed a comprehensive overhaul of the dashboard interface. Introduced advanced glassmorphism (`backdrop-filter: blur(20px)`) to the sidebar, softened structural corners (`border-radius: 18px`), and applied modern micro-animations and subtle drop-shadows across chat bubbles and input forms.
|
|
52
|
+
- **Color Harmony & Contrast**: Refined the Dark Mode palette by shifting the primary accent color to a sleek Cyan (`#32ADE6`). Adjusted typography across UI pills (Network Selectors, Trending Tokens) from harsh contrast to a harmonious, translucent off-white (`rgba(255, 255, 255, 0.85)`) for optimal readability without eye strain.
|
|
53
|
+
- **Chat Experience**: Redesigned the chat bubbles to distinctly separate user and agent messages using vibrant colored backgrounds for the user and elegant dark-glass styling for the agent, significantly improving spatial distinction.
|
|
54
|
+
|
|
55
|
+
### Native Channel Engine (Omni-Channel Integration)
|
|
56
|
+
- **Massive Architecture Overhaul**: Replaced the legacy hardcoded Telegram/Discord gateway with a highly scalable `ChannelManager`. Nyxora now natively and dynamically supports 19 distinct messaging platforms without requiring external sidecars.
|
|
57
|
+
- **Dynamic CLI Configuration**: Overhauled `setup.ts` to dynamically detect and register available channels, allowing users to select and configure credentials seamlessly via `nyxora start`.
|
|
58
|
+
- **19 Native SDK Implementations**: Successfully integrated and compiled native event listeners, Webhooks, and Socket Modes for WhatsApp (Baileys), Slack (Bolt Socket Mode), LINE, Microsoft Teams, Mattermost, Matrix, Google Chat, Synology, Nextcloud, Zalo, Twitch, iMessage, IRC, QQ Bot, Nostr, SMS, and Voice.
|
|
59
|
+
|
|
60
|
+
### Playbook Ecosystem & Automation
|
|
61
|
+
- **Playbook Recorder (Auto-Learn)**: Introduced a powerful Auto-Learn capability (CRITICAL RULE 7) allowing the OS Agent to dynamically record terminal workflows, abstract them into markdown instructions, and autonomously generate new reusable SOPs (Playbooks) based on chat history.
|
|
62
|
+
- **Skill Store Dashboard (Split-Pane UI)**: Built a brand-new native Skill Store interface in the dashboard (`Playbooks.tsx`), enabling users to browse, edit, and manage their local AI playbooks seamlessly via a modern split-pane editor without touching the terminal.
|
|
63
|
+
|
|
64
|
+
### Features & Architecture
|
|
65
|
+
- **Self-Learning & Continuous Improvement**: Transformed Nyxora into a continuously evolving AI. The OS Agent (`osAgent.ts`) now natively injects narrative profiles (`MEMORY.md` and `USER.md`) directly into the system prompt at the start of every session.
|
|
66
|
+
- **Asynchronous Background Review**: Engineered a non-blocking background auditor (`triggerBackgroundReview`) that executes silently after every interaction. The agent uses LangChain to evaluate recent conversations, autonomously identifying user preferences, extracting reusable workflows, and dynamically creating or patching its own skills (`skill_manager.py`) without user intervention.
|
|
67
|
+
|
|
68
|
+
### Bug Fixes & Improvements
|
|
69
|
+
- **Streaming UI Text Duplication & Glitch Fix**: Resolved a critical issue in the multi-turn streaming architecture where LLM "thought process" text (generated before a tool call) would leak and concatenate with the final answer on Telegram. Implemented a robust `[CLEAR_STREAM]` control signal that gracefully resets the message draft and displays a universal `⏳ Processing...` placeholder, completely eradicating message bubble collapse and visual jitter during tool execution.
|
|
70
|
+
|
|
7
71
|
## [26.7.4]
|
|
8
72
|
### Features & Architecture
|
|
9
73
|
- **Cognitive Critic Engine Enhancements (Staleness Detection)**: Added a multilingual time-sensitive detection rule to the Critic Engine (`critic.py`). By injecting the current UTC datetime, the Critic now explicitly flags answers containing time-sensitive keywords (e.g., "today", "kemarin", "now") if they rely on stale training memory rather than fresh tool execution.
|
package/README.md
CHANGED
|
@@ -72,7 +72,7 @@ It operates under a **Zero-Trust, Defense-in-Depth Cryptographically Bound Human
|
|
|
72
72
|
|
|
73
73
|
### Advanced Security Architecture
|
|
74
74
|
* **🛡️ On-Chain AI Kill-Switch**: Nyxora is governed by a Base Smart Contract (`NyxoraAgentRegistry`). Users have absolute cryptographic power to instantly paralyze the AI's on-chain execution if compromised, solving the Web3 AI safety dilemma. [Read more about our Base Architecture](https://nyxoraai.github.io/Nyxora/smart-contract)
|
|
75
|
-
* **
|
|
75
|
+
* **6-Tier Hybrid Architecture**: Nyxora is split into isolated microservices: **Dashboard** (Port 5173), **MCP Server** (Port 3001), **Core LLM** (Port 3000), **ML Engine** (Python Sidecar on Port 8000), **Policy Engine** (Unix Socket), and **Signer Vault** (Unix Socket).
|
|
76
76
|
* **DeFi & Market Configuration BYOK & UI Masking**: All aggregator, provider, and oracle API keys are strictly isolated via a Bring Your Own Keys (BYOK) architecture into heavily guarded `~/.nyxora/defi_keys.yaml` and `~/.nyxora/market_keys.yaml` files. The local web Dashboard masks these injected secrets using `***********` and `IS_SET` censorship, completely neutralizing malicious browser extensions from exfiltrating your keys.
|
|
77
77
|
* **Approval Replay Protection (Nonce Guard)**: Transactions requested by the AI are drafted as hashes and signed with a randomized 16-byte Nonce. The `/api/transactions/:id/approve` endpoint strictly enforces Nonce matching to completely eliminate double-spending and Replay Attacks.
|
|
78
78
|
* **Native Asset Parameter Tampering Protection**: The internal cryptographic HMAC signature rigorously binds `toAddress`, `txData`, and `valueWei`, rendering the system mathematically immune to Native Token (ETH/BNB) destination or amount hijacking via Indirect Prompt Injections.
|
|
@@ -121,15 +121,50 @@ It operates under a **Zero-Trust, Defense-in-Depth Cryptographically Bound Human
|
|
|
121
121
|
|
|
122
122
|
## 📐 Architecture Workflow
|
|
123
123
|
|
|
124
|
-
The following diagram illustrates Nyxora's **
|
|
124
|
+
The following diagram illustrates Nyxora's **6-Tier Hybrid Architecture**, showing the isolated communication channels across the ecosystem.
|
|
125
125
|
|
|
126
|
-
|
|
126
|
+
```mermaid
|
|
127
|
+
graph TD
|
|
128
|
+
classDef default fill:#1E1E2E,stroke:#4C4F69,stroke-width:2px,color:#CDD6F4;
|
|
129
|
+
classDef external fill:#11111B,stroke:#F38BA8,stroke-width:2px,color:#F38BA8,stroke-dasharray: 5 5;
|
|
130
|
+
classDef ui fill:#89B4FA,stroke:#1E1E2E,stroke-width:2px,color:#11111B;
|
|
131
|
+
classDef core fill:#A6E3A1,stroke:#1E1E2E,stroke-width:2px,color:#11111B;
|
|
132
|
+
classDef policy fill:#F9E2AF,stroke:#1E1E2E,stroke-width:2px,color:#11111B;
|
|
133
|
+
classDef signer fill:#F38BA8,stroke:#1E1E2E,stroke-width:2px,color:#11111B;
|
|
134
|
+
classDef blockchain fill:#CBA6F7,stroke:#1E1E2E,stroke-width:2px,color:#11111B;
|
|
127
135
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
136
|
+
User["User / External Client"]:::external
|
|
137
|
+
|
|
138
|
+
Dashboard["Dashboard (UI)<br/>Port 5173"]:::ui
|
|
139
|
+
MCP["MCP Server<br/>Port 3001"]:::ui
|
|
140
|
+
|
|
141
|
+
Core["Core LLM Runtime<br/>Port 3000<br/>(NLP Parsing, Routing, Agent Logic)"]:::core
|
|
142
|
+
|
|
143
|
+
ML["ML Engine<br/>Port 8000"]:::core
|
|
144
|
+
Policy["Policy Engine (Guard)<br/>Unix Socket (IPC) / Loopback"]:::policy
|
|
145
|
+
Signer["Signer Vault (Safe)<br/>Unix Socket (IPC)"]:::signer
|
|
146
|
+
|
|
147
|
+
RPC["Blockchain RPC"]:::blockchain
|
|
148
|
+
|
|
149
|
+
User --> Dashboard
|
|
150
|
+
User --> MCP
|
|
151
|
+
|
|
152
|
+
Dashboard --> Core
|
|
153
|
+
MCP --> Core
|
|
154
|
+
|
|
155
|
+
Core <-->|" RAG & Math "| ML
|
|
156
|
+
Core -->|" Draft Transaction "| Policy
|
|
157
|
+
Policy -->|" Approved Payload "| Signer
|
|
158
|
+
Signer --> RPC
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
*Nyxora separates its duties into 6 independent layers for absolute security and cognitive depth:*
|
|
162
|
+
1. **🖥️ Dashboard (UI)**: A premium local React interface for real-time monitoring and conversational execution.
|
|
163
|
+
2. **🔌 MCP Server (Context Provider)**: An open standard interface to connect Nyxora with external AI environments like Claude Desktop natively.
|
|
164
|
+
3. **🧠 Core (The AI Brain)**: The Node.js intelligent assistant that strategizes and plans transactions, but **never** holds your funds.
|
|
165
|
+
4. **🧬 ML Engine (Cognitive Sidecar)**: A local Python/FastAPI sidecar running LangChain and HuggingFace models for hyper-fast Semantic RAG memory and Pandas-based technical market analysis.
|
|
166
|
+
5. **🛡️ Policy Engine (The Guard)**: The security guard that verifies the Brain's plans. If the AI attempts to send funds exceeding your set limits, this engine automatically blocks it.
|
|
167
|
+
6. **🔒 Signer Vault (The Safe)**: The offline vault where your Private Keys **and highly sensitive 3rd-party tokens (e.g., Google Workspace OAuth)** are securely locked natively in your OS Keyring. It only signs transactions after they pass all rigorous security checks.
|
|
133
168
|
|
|
134
169
|
### Web3 Separation of Concerns (Zero-Trust Routing)
|
|
135
170
|
Within the AI Brain, the Web3 codebase is strictly divided to prevent the LLM from hallucinating or maliciously manipulating low-level routing paths:
|
package/dist/launcher.js
CHANGED
|
@@ -71,7 +71,6 @@ const spawnService = (name, command, args, env, inheritStdio = false, cwd) => {
|
|
|
71
71
|
try {
|
|
72
72
|
const yaml = require('yaml');
|
|
73
73
|
const configPath = path_1.default.join(process.env.HOME || process.env.USERPROFILE || '', '.nyxora', 'config', 'config.yaml');
|
|
74
|
-
// Fallback check just in case it hasn't migrated yet
|
|
75
74
|
const actualConfigPath = fs_1.default.existsSync(configPath) ? configPath : path_1.default.join(process.env.HOME || process.env.USERPROFILE || '', '.nyxora', 'config.yaml');
|
|
76
75
|
if (fs_1.default.existsSync(actualConfigPath)) {
|
|
77
76
|
const configStr = fs_1.default.readFileSync(actualConfigPath, 'utf8');
|
|
@@ -89,7 +88,12 @@ const spawnService = (name, command, args, env, inheritStdio = false, cwd) => {
|
|
|
89
88
|
}
|
|
90
89
|
}
|
|
91
90
|
catch (e) { }
|
|
92
|
-
|
|
91
|
+
console.log('\n[Launcher] Shutting down all services due to emergency shutdown...');
|
|
92
|
+
children.forEach(c => c.kill());
|
|
93
|
+
// Give children time to exit cleanly
|
|
94
|
+
setTimeout(() => {
|
|
95
|
+
process.exit(1);
|
|
96
|
+
}, 1000);
|
|
93
97
|
return;
|
|
94
98
|
}
|
|
95
99
|
console.log(`[Launcher] Restarting ${name} in 3 seconds... (Attempt ${crashCount}/5)`);
|
|
@@ -139,21 +143,69 @@ setTimeout(() => {
|
|
|
139
143
|
children.push(policy);
|
|
140
144
|
setTimeout(() => {
|
|
141
145
|
// Spawn ML Engine (Python Sidecar)
|
|
142
|
-
|
|
146
|
+
// Cross-platform: Windows uses Scripts/, Unix uses bin/
|
|
147
|
+
const IS_WINDOWS_LAUNCHER = process.platform === 'win32';
|
|
148
|
+
const pythonBinDir = IS_WINDOWS_LAUNCHER ? 'Scripts' : 'bin';
|
|
149
|
+
const pythonExe = IS_WINDOWS_LAUNCHER ? 'python.exe' : 'python';
|
|
150
|
+
const pythonPath = path_1.default.join(process.env.HOME || process.env.USERPROFILE || '', '.nyxora', 'ml-engine', 'venv', pythonBinDir, pythonExe);
|
|
143
151
|
if (fs_1.default.existsSync(pythonPath)) {
|
|
144
|
-
|
|
152
|
+
let mlDir = path_1.default.join(__dirnameResolved, 'packages', 'ml-engine');
|
|
153
|
+
if (!fs_1.default.existsSync(mlDir))
|
|
154
|
+
mlDir = path_1.default.join(__dirnameResolved, '..', 'packages', 'ml-engine');
|
|
145
155
|
const mlArgs = ['-m', 'uvicorn', 'main:app', '--host', '127.0.0.1', '--port', '8000'];
|
|
146
156
|
const mlEngine = spawnService('ML Engine', pythonPath, mlArgs, env, false, mlDir);
|
|
147
157
|
children.push(mlEngine);
|
|
148
158
|
}
|
|
149
159
|
else {
|
|
150
|
-
console.warn('[Launcher] Warning: Python virtual environment not found.
|
|
160
|
+
console.warn('[Launcher] Warning: Python virtual environment not found. ML Engine features (market analysis etc.) will be unavailable. Run: nyxora setup');
|
|
151
161
|
}
|
|
152
162
|
setTimeout(() => {
|
|
153
163
|
const corePath = path_1.default.join(__dirnameResolved, `packages/core/src/gateway/cli${ext}`);
|
|
154
164
|
const args = process.argv.slice(2);
|
|
155
165
|
const core = spawnService('Core', cmd, [...baseArgs, corePath, ...args], env, true);
|
|
156
166
|
children.push(core);
|
|
167
|
+
// --- AUTO-TUNNEL (Cloudflare) ---
|
|
168
|
+
// Respects config: set cloudflare_tunnel: false in ~/.nyxora/config/config.yaml to disable.
|
|
169
|
+
setTimeout(() => {
|
|
170
|
+
let cfEnabled = true;
|
|
171
|
+
try {
|
|
172
|
+
const yaml = require('yaml');
|
|
173
|
+
const configPath = path_1.default.join(nyxoraDir, 'config', 'config.yaml');
|
|
174
|
+
const fallbackPath = path_1.default.join(nyxoraDir, 'config.yaml');
|
|
175
|
+
const actualPath = fs_1.default.existsSync(configPath) ? configPath : fallbackPath;
|
|
176
|
+
if (fs_1.default.existsSync(actualPath)) {
|
|
177
|
+
const cfg = yaml.parse(fs_1.default.readFileSync(actualPath, 'utf8'));
|
|
178
|
+
if (cfg?.cloudflare_tunnel === false) {
|
|
179
|
+
cfEnabled = false;
|
|
180
|
+
console.log('[Launcher] Cloudflare Auto-Tunnel is disabled by config (cloudflare_tunnel: false).');
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
catch (e) { }
|
|
185
|
+
if (cfEnabled) {
|
|
186
|
+
console.log('[Launcher] Starting Auto-Tunnel (Cloudflare) on port 3000...');
|
|
187
|
+
const cf = (0, child_process_1.spawn)('npx', ['cloudflared', 'tunnel', '--url', 'http://localhost:3000'], { env, shell: true });
|
|
188
|
+
children.push({
|
|
189
|
+
kill: () => { try {
|
|
190
|
+
process.kill(cf.pid, 'SIGTERM');
|
|
191
|
+
}
|
|
192
|
+
catch (e) { } },
|
|
193
|
+
forceKill: () => { try {
|
|
194
|
+
process.kill(cf.pid, 'SIGKILL');
|
|
195
|
+
}
|
|
196
|
+
catch (e) { } }
|
|
197
|
+
});
|
|
198
|
+
cf.stderr.on('data', (data) => {
|
|
199
|
+
const msg = data.toString();
|
|
200
|
+
const match = msg.match(/https:\/\/[a-zA-Z0-9-]+\.trycloudflare\.com/);
|
|
201
|
+
if (match) {
|
|
202
|
+
const url = match[0];
|
|
203
|
+
console.log(`\n[Auto-Tunnel] Secure Public URL generated: ${url}\n`);
|
|
204
|
+
fs_1.default.writeFileSync(path_1.default.join(nyxoraDir, 'public_url.txt'), url, 'utf8');
|
|
205
|
+
}
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
}, 3000);
|
|
157
209
|
}, 1000);
|
|
158
210
|
}, 1000);
|
|
159
211
|
}, 1000);
|
|
@@ -173,11 +225,17 @@ const cleanup = () => {
|
|
|
173
225
|
}
|
|
174
226
|
catch (e) { }
|
|
175
227
|
});
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
228
|
+
// pkill is Unix-only — skip on Windows
|
|
229
|
+
if (process.platform !== 'win32') {
|
|
230
|
+
try {
|
|
231
|
+
require('child_process').execSync('pkill -f ts-node');
|
|
232
|
+
}
|
|
233
|
+
catch (e) { }
|
|
234
|
+
try {
|
|
235
|
+
require('child_process').execSync('pkill -f uvicorn');
|
|
236
|
+
}
|
|
237
|
+
catch (e) { }
|
|
179
238
|
}
|
|
180
|
-
catch (e) { }
|
|
181
239
|
process.exit(0);
|
|
182
240
|
}, 1000);
|
|
183
241
|
};
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.startBridgeWatcher = startBridgeWatcher;
|
|
4
4
|
const transactionManager_1 = require("./transactionManager");
|
|
5
|
-
const telegram_1 = require("../
|
|
5
|
+
const telegram_1 = require("../channels/telegram");
|
|
6
6
|
const parser_1 = require("../config/parser");
|
|
7
7
|
// In a real production environment, this would use the @eth-optimism/sdk
|
|
8
8
|
// to fetch the Merkle Proof and call proveWithdrawalTransaction on L1.
|
|
@@ -39,7 +39,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
39
39
|
exports.cronManager = void 0;
|
|
40
40
|
const croner_1 = require("croner");
|
|
41
41
|
const parser_1 = require("../config/parser");
|
|
42
|
-
const telegram_1 = require("../
|
|
42
|
+
const telegram_1 = require("../channels/telegram");
|
|
43
43
|
const crypto_1 = require("crypto");
|
|
44
44
|
const picocolors_1 = __importDefault(require("picocolors"));
|
|
45
45
|
class CronManager {
|
|
@@ -8,9 +8,18 @@ class OpenAIAdapter {
|
|
|
8
8
|
}
|
|
9
9
|
async chat(request) {
|
|
10
10
|
const response = await this.client.chat.completions.create(request);
|
|
11
|
+
let content = response.choices[0].message.content || '';
|
|
12
|
+
let reasoning = response.choices[0].message.reasoning_content || null;
|
|
13
|
+
// Extract <thinking> tags from content if present
|
|
14
|
+
const thinkingMatch = content.match(/<(think|thought|thinking|reasoning|analysis|reflection)>([\s\S]*?)<\/\1>/i);
|
|
15
|
+
if (thinkingMatch) {
|
|
16
|
+
reasoning = (reasoning || '') + thinkingMatch[2].trim();
|
|
17
|
+
content = content.replace(/<(think|thought|thinking|reasoning|analysis|reflection)>[\s\S]*?<\/\1>\n?/i, '').trim();
|
|
18
|
+
}
|
|
11
19
|
return {
|
|
12
20
|
message: {
|
|
13
|
-
content:
|
|
21
|
+
content: content || null,
|
|
22
|
+
reasoning_content: reasoning || null,
|
|
14
23
|
tool_calls: response.choices[0].message.tool_calls
|
|
15
24
|
},
|
|
16
25
|
usage: response.usage ? { total_tokens: response.usage.total_tokens } : undefined
|
|
@@ -20,6 +29,7 @@ class OpenAIAdapter {
|
|
|
20
29
|
try {
|
|
21
30
|
const streamRes = await this.client.chat.completions.create({ ...request, stream: true });
|
|
22
31
|
let fullContent = '';
|
|
32
|
+
let reasoningContent = '';
|
|
23
33
|
const toolCallsMap = {};
|
|
24
34
|
for await (const chunk of streamRes) {
|
|
25
35
|
const delta = chunk.choices[0]?.delta;
|
|
@@ -27,6 +37,9 @@ class OpenAIAdapter {
|
|
|
27
37
|
fullContent += delta.content;
|
|
28
38
|
onChunk(delta.content);
|
|
29
39
|
}
|
|
40
|
+
if (delta?.reasoning_content || delta?.reasoning) {
|
|
41
|
+
reasoningContent += (delta.reasoning_content || delta.reasoning);
|
|
42
|
+
}
|
|
30
43
|
if (delta?.tool_calls) {
|
|
31
44
|
for (const tc of delta.tool_calls) {
|
|
32
45
|
if (!toolCallsMap[tc.index]) {
|
|
@@ -44,9 +57,16 @@ class OpenAIAdapter {
|
|
|
44
57
|
}
|
|
45
58
|
}
|
|
46
59
|
const toolCalls = Object.values(toolCallsMap);
|
|
60
|
+
// Post-process to extract <thinking> tags that were streamed as part of content
|
|
61
|
+
const thinkingMatch = fullContent.match(/<(think|thought|thinking|reasoning|analysis|reflection|ant-thinking|ant_thinking)[^>]*>([\s\S]*?)<\/\1>/i);
|
|
62
|
+
if (thinkingMatch) {
|
|
63
|
+
reasoningContent = (reasoningContent || '') + thinkingMatch[2].trim();
|
|
64
|
+
fullContent = fullContent.replace(/<(think|thought|thinking|reasoning|analysis|reflection|ant-thinking|ant_thinking)[^>]*>[\s\S]*?<\/\1>\n?/i, '').trim();
|
|
65
|
+
}
|
|
47
66
|
return {
|
|
48
67
|
message: {
|
|
49
68
|
content: fullContent || null,
|
|
69
|
+
reasoning_content: reasoningContent || null,
|
|
50
70
|
tool_calls: toolCalls.length > 0 ? toolCalls : undefined
|
|
51
71
|
}
|
|
52
72
|
};
|
|
@@ -55,6 +75,7 @@ class OpenAIAdapter {
|
|
|
55
75
|
// Fallback to non-streaming if streaming fails
|
|
56
76
|
const chatRes = await this.chat(request);
|
|
57
77
|
if (chatRes.message.content) {
|
|
78
|
+
onChunk('[CLEAR_STREAM]');
|
|
58
79
|
onChunk(chatRes.message.content);
|
|
59
80
|
}
|
|
60
81
|
return chatRes;
|
|
@@ -149,11 +170,15 @@ class AnthropicAdapter {
|
|
|
149
170
|
max_tokens: request.max_tokens || 4096
|
|
150
171
|
});
|
|
151
172
|
let contentStr = null;
|
|
173
|
+
let reasoningStr = null;
|
|
152
174
|
let toolCalls = [];
|
|
153
175
|
for (const block of response.content) {
|
|
154
176
|
if (block.type === 'text') {
|
|
155
177
|
contentStr = (contentStr || '') + block.text;
|
|
156
178
|
}
|
|
179
|
+
else if (block.type === 'thinking') {
|
|
180
|
+
reasoningStr = (reasoningStr || '') + block.thinking;
|
|
181
|
+
}
|
|
157
182
|
else if (block.type === 'tool_use') {
|
|
158
183
|
toolCalls.push({
|
|
159
184
|
id: block.id,
|
|
@@ -165,9 +190,17 @@ class AnthropicAdapter {
|
|
|
165
190
|
});
|
|
166
191
|
}
|
|
167
192
|
}
|
|
193
|
+
if (contentStr) {
|
|
194
|
+
const thinkingMatch = contentStr.match(/<(think|thought|thinking|reasoning|analysis|reflection|ant-thinking|ant_thinking)[^>]*>([\s\S]*?)<\/\1>/i);
|
|
195
|
+
if (thinkingMatch) {
|
|
196
|
+
reasoningStr = (reasoningStr || '') + thinkingMatch[2].trim();
|
|
197
|
+
contentStr = contentStr.replace(/<(think|thought|thinking|reasoning|analysis|reflection|ant-thinking|ant_thinking)[^>]*>[\s\S]*?<\/\1>\n?/i, '').trim();
|
|
198
|
+
}
|
|
199
|
+
}
|
|
168
200
|
return {
|
|
169
201
|
message: {
|
|
170
|
-
content: contentStr,
|
|
202
|
+
content: contentStr || null,
|
|
203
|
+
reasoning_content: reasoningStr || null,
|
|
171
204
|
tool_calls: toolCalls.length > 0 ? toolCalls : undefined
|
|
172
205
|
},
|
|
173
206
|
usage: response.usage ? { total_tokens: response.usage.input_tokens + response.usage.output_tokens } : undefined
|
|
@@ -233,12 +266,16 @@ class AnthropicAdapter {
|
|
|
233
266
|
max_tokens: request.max_tokens || 4096
|
|
234
267
|
});
|
|
235
268
|
let fullContent = '';
|
|
269
|
+
let reasoningContent = '';
|
|
236
270
|
const toolCalls = [];
|
|
237
271
|
for await (const event of stream) {
|
|
238
272
|
if (event.type === 'content_block_delta' && event.delta.type === 'text_delta') {
|
|
239
273
|
fullContent += event.delta.text;
|
|
240
274
|
onChunk(event.delta.text);
|
|
241
275
|
}
|
|
276
|
+
if (event.type === 'content_block_delta' && event.delta.type === 'thinking_delta') {
|
|
277
|
+
reasoningContent += event.delta.thinking;
|
|
278
|
+
}
|
|
242
279
|
if (event.type === 'content_block_start' && event.content_block.type === 'tool_use') {
|
|
243
280
|
toolCalls.push({ id: event.content_block.id, type: 'function', function: { name: event.content_block.name, arguments: '' } });
|
|
244
281
|
}
|
|
@@ -248,10 +285,22 @@ class AnthropicAdapter {
|
|
|
248
285
|
last.function.arguments += event.delta.partial_json;
|
|
249
286
|
}
|
|
250
287
|
}
|
|
251
|
-
|
|
288
|
+
if (fullContent) {
|
|
289
|
+
const thinkingMatch = fullContent.match(/<(think|thought|thinking|reasoning|analysis|reflection|ant-thinking|ant_thinking)[^>]*>([\s\S]*?)<\/\1>/i);
|
|
290
|
+
if (thinkingMatch) {
|
|
291
|
+
reasoningContent = (reasoningContent || '') + thinkingMatch[2].trim();
|
|
292
|
+
fullContent = fullContent.replace(/<(think|thought|thinking|reasoning|analysis|reflection|ant-thinking|ant_thinking)[^>]*>[\s\S]*?<\/\1>\n?/i, '').trim();
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
return { message: { content: fullContent || null, reasoning_content: reasoningContent || null, tool_calls: toolCalls.length > 0 ? toolCalls : undefined } };
|
|
252
296
|
}
|
|
253
297
|
catch {
|
|
254
|
-
|
|
298
|
+
const chatRes = await this.chat(request);
|
|
299
|
+
if (chatRes.message.content) {
|
|
300
|
+
onChunk('[CLEAR_STREAM]');
|
|
301
|
+
onChunk(chatRes.message.content);
|
|
302
|
+
}
|
|
303
|
+
return chatRes;
|
|
255
304
|
}
|
|
256
305
|
}
|
|
257
306
|
}
|
|
@@ -385,9 +434,18 @@ class GeminiAdapter {
|
|
|
385
434
|
if (data.usageMetadata && data.usageMetadata.totalTokenCount) {
|
|
386
435
|
totalTokens = data.usageMetadata.totalTokenCount;
|
|
387
436
|
}
|
|
437
|
+
let reasoningContent = null;
|
|
438
|
+
if (contentStr) {
|
|
439
|
+
const thinkingMatch = contentStr.match(/<(think|thought|thinking|reasoning|analysis|reflection|ant-thinking|ant_thinking)[^>]*>([\s\S]*?)<\/\1>/i);
|
|
440
|
+
if (thinkingMatch) {
|
|
441
|
+
reasoningContent = thinkingMatch[2].trim();
|
|
442
|
+
contentStr = contentStr.replace(/<(think|thought|thinking|reasoning|analysis|reflection|ant-thinking|ant_thinking)[^>]*>[\s\S]*?<\/\1>\n?/i, '').trim();
|
|
443
|
+
}
|
|
444
|
+
}
|
|
388
445
|
return {
|
|
389
446
|
message: {
|
|
390
|
-
content: contentStr,
|
|
447
|
+
content: contentStr || null,
|
|
448
|
+
reasoning_content: reasoningContent || null,
|
|
391
449
|
tool_calls: toolCalls.length > 0 ? toolCalls : undefined
|
|
392
450
|
},
|
|
393
451
|
usage: totalTokens > 0 ? { total_tokens: totalTokens } : undefined
|
|
@@ -504,13 +562,26 @@ class GeminiAdapter {
|
|
|
504
562
|
}
|
|
505
563
|
}
|
|
506
564
|
}
|
|
565
|
+
let reasoningContent = null;
|
|
566
|
+
if (contentStr) {
|
|
567
|
+
const thinkingMatch = contentStr.match(/<(think|thought|thinking|reasoning|analysis|reflection|ant-thinking|ant_thinking)[^>]*>([\s\S]*?)<\/\1>/i);
|
|
568
|
+
if (thinkingMatch) {
|
|
569
|
+
reasoningContent = thinkingMatch[2].trim();
|
|
570
|
+
contentStr = contentStr.replace(/<(think|thought|thinking|reasoning|analysis|reflection|ant-thinking|ant_thinking)[^>]*>[\s\S]*?<\/\1>\n?/i, '').trim();
|
|
571
|
+
}
|
|
572
|
+
}
|
|
507
573
|
return {
|
|
508
|
-
message: { content: contentStr || null, tool_calls: toolCalls.length > 0 ? toolCalls : undefined },
|
|
574
|
+
message: { content: contentStr || null, reasoning_content: reasoningContent || null, tool_calls: toolCalls.length > 0 ? toolCalls : undefined },
|
|
509
575
|
usage: totalTokens > 0 ? { total_tokens: totalTokens } : undefined
|
|
510
576
|
};
|
|
511
577
|
}
|
|
512
578
|
catch {
|
|
513
|
-
|
|
579
|
+
const chatRes = await this.chat(request);
|
|
580
|
+
if (chatRes.message.content) {
|
|
581
|
+
onChunk('[CLEAR_STREAM]');
|
|
582
|
+
onChunk(chatRes.message.content);
|
|
583
|
+
}
|
|
584
|
+
return chatRes;
|
|
514
585
|
}
|
|
515
586
|
}
|
|
516
587
|
}
|
|
@@ -55,7 +55,7 @@ class NyxDaemon {
|
|
|
55
55
|
this.isProcessing = false;
|
|
56
56
|
return;
|
|
57
57
|
}
|
|
58
|
-
//
|
|
58
|
+
// Send conversation history to Python ML Engine for cognitive modeling
|
|
59
59
|
const res = await fetch('http://127.0.0.1:8000/cognitive/reason', {
|
|
60
60
|
method: 'POST',
|
|
61
61
|
headers: { 'Content-Type': 'application/json' },
|
|
@@ -82,7 +82,7 @@ class NyxDaemon {
|
|
|
82
82
|
}
|
|
83
83
|
}
|
|
84
84
|
catch (e) {
|
|
85
|
-
console.error(picocolors_1.default.red('[Nyx] Failed to process traits from Python'), traits);
|
|
85
|
+
console.error(picocolors_1.default.red('[Nyx] Failed to process traits from Python: ' + e.message), traits);
|
|
86
86
|
}
|
|
87
87
|
}
|
|
88
88
|
catch (e) {
|