מצב נוכחי
- lastUpdate: 2026-10-04 09:44 CEST
- currentStage: Providers Cleanup
- next: סיכום שלבים 1-8 + orchestration: תיעוד סופי של כל מה שנבנה, קבצים, וסטטוס
- side: radiant
- lastDecision: Gap Analysis vs. Instinct: זוהו 10 פערים, 4 קריטיים (Audio/Browser/VirtualCard/Interceptor)
התוכנית
תוכנית השילוב Ruby ↔ Radiant (התוכנית המלאה)
עדכון אוטומטי דרך `./logs.sh`. לקריאה: `./logs.sh plan`.
מטרה
לקחת את Ruby (<code>ruby.turqizai.com</code>) ו-API-Bank (<code>apibank.turqizai.com</code>) ולבנות אותם
מחדש על בסיס Radiant — בשיטת <strong>מיזוג, לא שכתוב</strong>. שימוש ביכולות הקיימות של Radiant
במקום לבנות מודלים מ-0.
החלטות ליבה (מקוצר — מלא ב-decisions.md)
| נכס | החלטה |
|---|---|
| RCP | 🟢 אמץ (IP ייחודי, 44 intents) |
| Canonical API | 🟢 אמץ |
| RFB | 🟡 החלף ב-MCP |
| Federation | 🟡 מיזוג חלקי (מעל Nodes) |
| Multi-tenant | 🟢 ליבה (tenantId מנדטורי) |
| DB | ✅ PostgreSQL 16 + RLS |
| בידוד | ✅ מדורג (רמות 1/2/3) |
שלבים
| שלב | תיאור | מצב |
|---|---|---|
| שלב 1 | RCP Schema as Radiant Skill | ✅ done |
| שלב 2 | Tenant Model (tenantId, בידוד, control plane) | ✅ done |
| שלב 3 | Intent Router (44 intents → כלים) | ✅ done |
| שלב 4 | Intent Discovery (דינמי controlled) | ✅ done |
| שלב 5 | Desktop Arm ↔ Node (אופציה B: Node אמיתי) | ✅ done |
| שלב 5b | Windows installer (thin client) | ✅ done |
| שלב 5c | tenant→node provisioning (רמות 1/2/3) | ✅ done |
| שלב 6 | Browser Extension ↔ Radiant | ⬜ todo |
| שלב 7 | Federation on top of Nodes (tenant-scoping) | ⬜ todo |
| שלב 8 | Events → Cron/webhooks | ⬜ todo |
| — | orchestration של 500 tenants | ⬜ todo |
מה נבנה בפועל (קבצים)
Radiant skill (rcp)
<code>/root/.openclaw-radiant/workspace/skills/rcp/</code>:
- `SKILL.md`, `references/intents.md` (44), `envelope.md`, `tenant-model.md`,
<code>federation.md</code>, <code>events.md</code> (36), <code>intent-router.md</code>, <code>intent-discovery.md</code>,
<code>desktop-arm.md</code>, <code>desktop-arm-adapter.js</code>, <code>tenant-node-provisioning.md</code>
Installer + provisioning
<code>/root/.openclaw-shared/radiant-desktop-installer/</code>:
- `install-radiant-node.ps1` (Windows bootstrap)
- `radiant-desktop-node.nsi` (NSIS wrapper)
- `provision-tenant.sh` (isolation levels 1/2/3)
- `migrate-tenant-level.sh` (מעבר רמה)
- `tenant-node-provisioning.sql` (PostgreSQL + RLS)
רמות בידוד (isolation levels)
כל tenant נבנה מאותו <code>template</code> עם פרמטר אחד <code>--isolation-level</code> (1|2|3).
| רמה | מה נפרד | עלות | מתי |
|---|---|---|---|
| **1** | process + schema (אותו Postgres) | נמוכה | דמו / free |
| **2** | process + DB instance נפרד | בינונית | לקוחות משלמים |
| **3** | VM/container + DB + KMS | גבוהה | Pay / PCI |
<strong>עקרון הרמה-אגנוסטי:</strong> הקוד והנתונים <strong>לא משתנים</strong> בין רמות — רק "איפה דברים רצים"
(process vs VM) ו"איפה נשמרים מפתחות" (local vs KMS) משתנים.
לכן מעבר בין רמות הוא פשוט:
migrate-tenant-level.sh <tenantId> <newLevel>
(dump/restore + עדכון connection string + secret provider) — <strong>אין שינוי קוד או נתונים.</strong>
<strong>הערה חשובה (בנקאות/PCI):</strong> רמה 1 כשלעצמה אינה מספקת ביטחון ברמת בנק. בשביל זה צריך
בנוסף הצפנה-at-rest, KMS, audit, וסגמנטציית רשת — ולצורכי Pay/PCI נדרשת רמה 3.
עקרונות מוטמעים
1. <code>tenantId</code> מנדטורי בכל הודעה/חיבור/אירוע (anti-spoofing: מ-auth, לא מהלקוח)
2. בידוד מלא (workspace, memory, sessions, secrets — per-tenant)
3. Control plane: platform_admin / tenant_admin / tenant_user
4. Provisioning: משתמש חדש = אינסטנס נקי + keys + config
5. קוד + נתונים קבועים בין רמות בידוד; רק "איפה רצים" + "איפה מפתחות" משתנים
Intents (RCP)
RCP Intents — רשימה מלאה + סכמות Payload
מקור: <code>turqiz-ai/ruby-ai/src/lib/rcp/schema.ts</code> (RCPIntentSchema + payload schemas).
Intents ליבה
פשוטים (ללא payload)
- `greet` — ברכה / לחיצת יד בין סוכנים
- `tour` — סיור מודרך
- `get_status` — סטטוס המערכת
CRM
| Intent | Payload |
|---|---|
| `create_lead` | `{ name?, email?, phone?, contact?, source?, service?, metadata? }` |
| `update_lead` | `{ leadId, status?, name?, email?, phone? }` |
| `list_leads` | `{ limit?, status? }` |
| `get_conversations` | `{ limit?, sessionId? }` |
Calendar / Appointments
| Intent | Payload |
|---|---|
| `book_appointment` | `{ name?, date?, time?, purpose?, userId? }` (תומך ב"מחר"/"היום"/dd.mm.yyyy) |
| `check_availability` | `{ date? }` |
| `create_event` | `{ title?, subject?, date?, time?, duration?, attendees? }` |
Communication
| Intent | Payload |
|---|---|
| `send_message` | `{ to, message, channel? }` |
| `send_email` | `{ to?, subject?, content?, body? }` |
| `check_email` | `{ count? }` |
Payments
| Intent | Payload |
|---|---|
| `place_order` | `{ ... }` (items, amount) |
| `payment` | `{ ... }` (process/query) |
Knowledge / Query
| Intent | Payload |
|---|---|
| `query` | `{ query, type? }` |
| `query_users` | `{ ... }` |
| `query_posts` | `{ ... }` |
| `query_weather` | `{ location }` |
| `query_pokemon` | `{ name/id }` |
Search / Media
| Intent | Payload |
|---|---|
| `search_youtube` | `{ query?, q?, count? }` |
| `youtube_stats` | `{ channel? }` |
| `find_location` | `{ query, q? }` |
| `get_directions` | `{ from?, to? }` |
Code / Repo / CMS
| Intent | Payload |
|---|---|
| `github_status` | `{ owner?, repo? }` |
| `github_issues` | `{ owner?, repo?, limit? }` |
| `wp_posts` | `{ count? }` |
| `wp_create_post` | `{ title?, content? }` |
Analytics
| Intent | Payload |
|---|---|
| `analytics` | `{ metric?, range? }` |
Federation
| Intent | Payload |
|---|---|
| `create_connection` | `{ personalRuby, systemRuby, permissions, authMethod, callbackUrl? }` |
| `subscribe_events` | `{ subscriberRuby, eventType, callbackUrl, filters? }` |
Automation (n8n)
| Intent | Payload |
|---|---|
| `trigger_n8n_workflow` | `{ workflowId?, webhookUrl?, workflowName?, data?, payload? }` |
| `execute_n8n_node` | `{ nodeType, action?, parameters? }` |
Additional
| Intent | Payload |
|---|---|
| `configure` | `{ ... }` |
| `transfer_info` | `{ ... }` |
Priorities
<code>urgent | high | normal | low</code> — שדה <code>priority</code> אופציונלי בכל הודעה.
הוספת Intent חדש
כדי להוסיף intent חדש:
1. הוסף אותו לטבלה המתאימה כאן.
2. וודא ש-<code>intent-translator</code> (keyword map) מכיר אותו לשפה טבעית (עב/אנ).
3. וודא ש-<code>messages.ts</code> (intentHandler) מממש אותו.
4. עדכן את מונה ה-intents ב-SKILL.md.
הערה למיזוג ל-Radiant
ה-intent-translator (NLP) הופך ל-preprocessing לפני ה-agent. ה-intentHandler הופך
לניתוב ל-tools/ערוצי openClaw. כל intent חייב tenantId-scoped.
Desktop Arm ↔ Node
Desktop Arm ↔ Node — חיבור זרוע התפעול
**שלב 5:** חיבור אפליקציית Ruby Desktop אל המוח OpenClaw/Radiant **כזרוע Node אמיתית**.
החלטה אדריכלית
<strong>אופציה B — Node אמיתי של OpenClaw</strong> (לא adapter צדדי).
<code>openclaw node run</code> כבר מספק node host מובנה שמתחבר ל-Gateway WebSocket כ-<code>role: "node"</code>,
וחושף <code>system.run</code>, <code>system.which</code>, <code>system.execApprovals</code>. <strong>אין צורך לממש pairing/WS מאפס.</strong>
למה Node אמיתי עדיף על Adapter
| Adapter (A) | Node אמיתי (B) | |
|---|---|---|
| שרשרת | Radiant → adapter → שרת רובי → Mongo → poll(3s) → PC | Radiant → `exec(host=node)` → PC |
| תלות | שרת רובי (Mongo) חובה | אפס — חיבור ישיר |
| Latency | poll 3 שניות | push מיידי |
| מנצל OpenClaw | לא | `exec`/`file_*`/`screen`/`notify` מובנה |
מיפוי פקודות זרוע ←→ OpenClaw tool
| desktop type | OpenClaw node host | הערות |
|---|---|---|
| `shell` | `exec(host=node)` | system.run |
| `launch` / `kill` | `exec(host=node)` | הרצה/הריגת תהליך |
| `read_file` | `file_fetch` | קריאת קובץ |
| `write_file` | `file_write` | כתיבת קובץ |
| `list_dir` | `dir_list` | רשימת תיקייה |
| `system_info` / `list_running` | `nodes(device_info/status)` | מידע מערכת |
| `mkdir/delete/rename/copy/open` | `exec(host=node)` (FS) | או file_* |
| `organize` | סקריפט `exec(host=node)` | ארגון שולחן עבודה |
שרשרת היעד
Radiant → exec(host=node) / file_fetch / nodes(screen_snapshot) → PC (node host)
שימוש
# על ה-PC:
openclaw node run --host <gateway-host> --port 18789 --display-name "MSI"
# על ה-gateway:
openclaw devices list
openclaw devices approve <requestId>
openclaw nodes status
openclaw approvals allowlist add --node MSI "<cmd>"
מצב נוכחי
- ✅ מיפוי שני הצדדים + מפת כלים — הושלם
- ✅ אופציה A (Adapter) הוכחה מקצה-לקצה (shell + system_info פעלו על PC)
- ✅ החלטה סופית: אופציה B (Node אמיתי)
- ⬜ הפעלת node host על ה-PC + אישור pairing (ממתין לגישה)
- ⬜ allowlist + exec approvals + `tools.exec.host=node`
Code Mode (MCP)
Ruby Code Mode Engine (MCP) — Search-and-Execute
<strong>תאריך:</strong> 22 באוגוסט 2026 (עודכן 25 באוגוסט 2026)
<strong>סטטוס:</strong> ✅ Code Mode אמיתי מומש ונבדק live (25.8) — <code>execute_code</code> מריץ JS ב-sandbox
**עדכון 25.8.26:** הקטלוג אוחד לקובץ אחד — `integration-templates.ts` (5501 אינטגרציות). `pieces-catalog.ts` ו-`unified-catalog.ts` נמחקו. ראה `unified-catalog.md`.
הקונספט
במקום לחשוף עשרות כלי API נפרדים ל-LLM, המערכת חושפת <strong>2 כלי ליבה בלבד</strong> (תואם Cloudflare Code Mode):
1. <code>search</code> — חיפוש ושליפת חתימות API / templates מתוך ה-API Bank (<code>ruby.search</code>).
2. <code>execute</code> — <strong>הרצת JavaScript של המודל</strong> ב-sandbox מבודד (<code>ruby.execute</code> / <code>ruby.get</code> / <code>ruby.list</code>).
מימוש Code Mode אמיתי (23.8.2026) — חדש
| רכיב | מיקום | מה עושה |
|---|---|---|
| Sandbox JS אמיתי | `src/lib/api-bank/code-mode.ts` | `runCodeMode()` — node:vm מבודד + timeout, מריץ קוד שהמודל כותב |
| Endpoint | `src/app/api/codemode/route.ts` | `POST /api/codemode` |
| execute_code (MCP) | `src/lib/mcp/server.ts` | קורא `runCodeMode` — המודל שולח `code`, רץ עם אובייקט `ruby` |
<strong>אבטחה (מאומת live):</strong> <code>process</code>/<code>require</code>/<code>fetch</code> = undefined; timeout 5-8s קשיח; <code>tenantId</code> מוזרק מהשרת (anti-spoofing), לא מהקוד.
היתרונות
- חיסכון של 85%–90% בטוקנים ובזמני תגובה.
- שרשור פעולות מרובות (Chaining) בסבב יחיד במילישניות.
- בידוד טננטים ברמת ה-Sandbox וה-Postgres RLS.
- תאימות מלאה ל-Radiant, Claude Code, Cursor ו-OpenClaw.
איפה זה ממומש בפועל (api-bank)
| רכיב | מיקום | מה עושה |
|---|---|---|
| `execute` | `src/app/api/execute/route.ts` | `sdk.execute(integrationSlug, action, params, tenantId)` |
| `search` | `src/app/api/search/route.ts` | חיפוש templates (`q`, sort, limit) |
| `mcp` | `src/app/api/mcp/convert/route.ts` | MCP endpoint (RFB + talents) |
| SDK ליבה | `src/lib/api-bank/sdk.ts` (404 שורות) | `TurqizAPIBank` — ה-SDK המרכזי |
| Sandbox | `src/lib/api-bank/sandbox-engine.ts` | ביצוע mock/sandbox (sampleResponse + latency) |
| מנוע | `src/lib/api-bank/engine.ts` (386 שורות) | ניהול templates |
תשתית תומכת: <code>action-router.ts</code>, <code>pipeline-engine.ts</code>, <code>rate-limiter.ts</code>, <code>task-queue.ts</code>, <code>rcp-translator.ts</code>.
שלבי ביצוע (הושלמו)
- ✅ שלב א': הקמת שרת ה-MCP (`search` + `execute` + HTTP transport).
- ✅ שלב ב': מנוע ה-Sandbox המאובטח (sandbox-engine עם mock/latency ובידוד).
- ✅ שלב ג': מיפוי מתאמי API-Bank ל-SDK (`TurqizAPIBank.execute`).
- ✅ שלב ד': שילוב ב-Radiant ובעדכון ה-System Prompt.
- ✅ **שלב ה' (2026-08-22): MCP מוטמע (Option 2)** — שרת MCP רץ בתוך api-bank, STDIO ישיר ל-SDK.
איך זה ממומש בפועל (Option 2 — embedded STDIO)
<strong>החלטה:</strong> במקום server נפרד שעוטף את ה-REST (Option 1), נבנה שרת MCP <strong>מוטמע</strong> בתוך api-bank, מדבר ישירות עם ה-SDK (<code>actionRouter</code> / <code>apiBankEngine</code> / <code>key-vault</code>) ללא קפיצת HTTP נוספת.
| רכיב חדש | מיקום | מה עושה |
|---|---|---|
| שרת MCP | `src/lib/mcp/server.ts` | 9 כלים (buildServer) |
| כניסת STDIO | `src/mcp-serve.ts` | טוען `.env.local` + מתחבר ל-stdio |
| Script | `package.json` → `"mcp": "tsx src/mcp-serve.ts"` | הרצה |
| רישום OpenClaw | `mcp.servers.radiant-apibank` (openclaw.json) | npx tsx src/mcp-serve.ts, cwd=api-bank |
מפת הכלים (9 כלים)
| כלי | מקור | tenantId |
|---|---|---|
| `search_tools` | `apiBankEngine.listTemplates` (search/nameHe/tags) | — (ציבורי) |
| `execute_code` | `actionRouter.execute` (action→integration+rcpAction) | מ-auth (`x-api-key`) |
| `list_available_actions` | `actionRouter.listAvailableActions` | מ-auth |
| `gateway_status` | `actionRouter.authenticate` summary | מ-auth |
| `list_templates` | `apiBankEngine.listTemplates` (category/verified) | — |
| `get_template` | `apiBankEngine.getTemplate` + getActions | — |
| `test_integration` | `actionRouter.execute` (x-sandbox) | מ-auth |
| `manage_vault` | `key-vault` (store/list/get/delete) | פרמטר (ברירת default) |
| `federation_connections` | Mongo collection federation_* | — |
אנטי-ספופינג (tenantId)
- `execute_code` / `list_available_actions` / `gateway_status` — tenantId תמיד נקבע ע"י `actionRouter.authenticate` (hash של `x-api-key`/Bearer), **לא** מהלקוח.
- מפתח ה-API מוזרק env `APIBANK_API_KEY` / `RADIANT_API_KEY`.
- `manage_vault` — tenant עובר פרמטר, אך מוגן ע"י encryption per-tenant (`VAULT_MASTER_KEY`).
אימות (verified)
cd /root/.openclaw-radiant
openclaw mcp list # radiant-apibank
openclaw mcp doctor radiant-apibank --probe # ok
openclaw mcp probe radiant-apibank --json # 9 tools
הרצה ידנית:
cd /root/.openclaw/workspace/turqiz-ai/api-bank
npm run mcp # טוען .env.local אוטומטית
Gap Spec — פערים vs. Instinct
📋 Ruby/Radiant — System Specification
פערים ויכולות חסרות לסגירה vs. Instinct
<strong>גרסה:</strong> 1.0
<strong>תאריך:</strong> 1 באוקטובר 2026
<strong>מיועד לצוות:</strong> Planning & Engineering
<strong>סטטוס:</strong> Draft — ממתין לאישור
0. רקע ומטרה
המסמך מגדיר את <strong>10 הפערים הארכיטקטוניים</strong> שזוהו בהשוואה בין מערכת Instinct לבין Ruby/Radiant.
עבור כל פער מפורטים:
- **What** — מה הרכיב החסר
- **Why** — מה הסיכון ללא יישומו
- **How** — מפרט טכני, חוזה API, מבנה קבצים
- **Acceptance Criteria** — תנאי קבלה לבדיקת QA
תוכנית הביצוע: <strong>4 ספרינטים, ~8 שבועות.</strong>
🔴 SPRINT 1 — בסיס בטיחות ונורמליזציה
GAP-03: Pre-Execution Action Interceptor
מה זה ולמה זה חשוב
כרגע, כל בקשה ל-<code>execute_code</code> ול-<code>gateway_action</code> עוברת ישירות לביצוע — <strong>ללא בקרה.</strong>
Agent שגוי או prompt injection יכולים לגרום לפעולות הרסניות (מחיקת נתונים, תשלומים לא מורשים, שליחת הודעות לא מאושרות).
<strong>Instinct פתרו זאת עם:</strong>
- מודל קל (Guard LLM) שבודק כל תוכנית פעולה לפני ביצועה
- Policy Engine עם חוקים קשיחים (non-LLM deterministic rules)
- Prompt Injection Scrubber לנתונים חיצוניים
ארכיטקטורה
execute_code(script) / gateway_action(action)
│
▼
┌─────────────────────┐
│ ActionInterceptor │ ← middleware חדש
│ │
│ 1. PolicyEngine │ ← חוקים קשיחים (deterministic)
│ 2. GuardLLM check │ ← מודל קל לבדיקת הגיון
│ 3. InjectionScrub │ ← ניקוי prompt injection
│ 4. UserConfirmation │ ← אישור אנושי אם נדרש
└──────────┬──────────┘
│ approved
▼
Execution Engine
מבנה קבצים
/root/radiant/src/lib/safety/
├── action-interceptor.ts ← Middleware ראשי
├── policy-engine.ts ← חוקים קשיחים
├── guard-llm.ts ← בדיקת LLM קל
├── injection-scrubber.ts ← ניקוי Web Content
└── confirmation-flow.ts ← אישור WhatsApp/UI
חוזה API (TypeScript)
// policy-engine.ts
interface PolicyRule {
id: string;
condition: (action: AgentAction) => boolean;
block: boolean; // true = עצור ללא אפשרות override
requireConfirmation: boolean;
message: string;
}
const DEFAULT_POLICIES: PolicyRule[] = [
{
id: 'max-payment-no-confirm',
condition: (a) => a.type === 'payment' && a.amount > 50,
block: false,
requireConfirmation: true,
message: 'פעולת תשלום מעל ₪50 דורשת אישור מפורש'
},
{
id: 'block-bulk-delete',
condition: (a) => a.type === 'db_write' && a.operation === 'DELETE' && !a.where,
block: true,
requireConfirmation: false,
message: 'מחיקה ללא תנאי WHERE חסומה לחלוטין'
},
{
id: 'external-content-injection',
condition: (a) => a.sourceType === 'web_content' || a.sourceType === 'email_body',
block: false,
requireConfirmation: false,
message: 'תוכן מקור חיצוני — עובר ניקוי injection'
}
];
// action-interceptor.ts
async function interceptAction(
action: AgentAction,
context: TenantContext
): Promise<InterceptResult> {
// שלב 1: Policy Engine (deterministic)
const policyResult = policyEngine.evaluate(action, context);
if (policyResult.blocked) return { allow: false, reason: policyResult.message };
// שלב 2: Injection Scrubber
if (action.containsExternalContent) {
action = await injectionScrubber.clean(action);
}
// שלב 3: Guard LLM (lightweight)
const guardResult = await guardLLM.evaluate(action, context);
if (!guardResult.safe) return { allow: false, reason: guardResult.reason };
// שלב 4: אישור משתמש אם נדרש
if (policyResult.requireConfirmation) {
return { allow: false, pendingConfirmation: true, confirmationId: uuid() };
}
return { allow: true };
}
Acceptance Criteria
- [ ] תשלום מעל 50 ₪ → שליחת הודעת אישור למשתמש לפני ביצוע
- [ ] DELETE ללא WHERE → נחסם תמיד, מוחזרת שגיאה ברורה
- [ ] תוכן מאתר חיצוני עם `Ignore previous instructions` → מנוטרל
- [ ] פעולות רגילות (createLead, sendWhatsApp) → עוברות ב-<10ms overhead
GAP-05: Message Normalizer (Buffer & Aggregation)
מה זה ולמה זה חשוב
משתמש שולח 3 הודעות WhatsApp רצופות תוך 5 שניות ("תזמין לי שולחן", "ב-פינטי", "לשישי ב-8") — כרגע כל הודעה מטופלת בנפרד, ה-LLM מקבל קונטקסט מנותק ומגיב על כל הודעה בנפרד = 3 תגובות טיפשיות.
ארכיטקטורה
WhatsApp Webhook Event
│
▼
┌───────────────────┐
│ MessageBuffer │ ← Buffer per conversation_id
│ window: 5s │
│ maxSize: 10 msgs │
│ │
│ Timer Reset on │
│ each new message │
└─────────┬─────────┘
│ timeout / max reached
▼
┌───────────────────┐
│ Normalizer │
│ → join messages │
│ → single prompt │
└─────────┬─────────┘
▼
Radiant Orchestrator
חוזה API
// message-aggregator.ts
interface MessageBuffer {
conversationId: string;
tenantId: string;
messages: IncomingMessage[];
timer: NodeJS.Timeout;
}
class MessageAggregator {
private buffers: Map<string, MessageBuffer> = new Map();
private readonly WINDOW_MS = 5000; // 5 שניות
private readonly MAX_MESSAGES = 10;
async ingest(msg: IncomingMessage): Promise<void> {
const key = `${msg.tenantId}:${msg.conversationId}`;
if (this.buffers.has(key)) {
const buf = this.buffers.get(key)!;
clearTimeout(buf.timer); // איפוס הטיימר
buf.messages.push(msg);
if (buf.messages.length >= this.MAX_MESSAGES) {
await this.flush(key); // שלח מיד אם הגענו למקסימום
return;
}
} else {
this.buffers.set(key, { conversationId: msg.conversationId, tenantId: msg.tenantId, messages: [msg], timer: null! });
}
const buf = this.buffers.get(key)!;
buf.timer = setTimeout(() => this.flush(key), this.WINDOW_MS);
}
private async flush(key: string): Promise<void> {
const buf = this.buffers.get(key)!;
this.buffers.delete(key);
const combinedText = buf.messages.map(m => m.text).join('\n');
await orchestrator.dispatch({ ...buf.messages[0], text: combinedText });
}
}
Acceptance Criteria
- [ ] 3 הודעות תוך 5 שניות → מגיעות כ-Prompt יחיד ל-Orchestrator
- [ ] הודעה יחידה → זמן ל-LLM מוגדל ב-5s בלבד (acceptable delay)
- [ ] 10 הודעות → flush מיידי בלי לחכות 5s
- [ ] Buffer מתאפס per conversation_id, לא per tenant
🔴 SPRINT 2 — Browser Power
GAP-04: Server-Side Headless Browser Pool
מה זה ולמה זה חשוב
כרגע ה-Browser Automation (TOSP) רץ <strong>בדפדפן של המשתמש</strong> (Chrome Extension) — כלומר:
- המשתמש חייב להיות עם Chrome פתוח
- לא ניתן לבצע משימות ברקע
- לא ניתן לנהל Browser בשם לקוח B2B (multi-tenant)
<strong>Instinct מנהלים Pool של דפדפנים ב-Server עם MicroVM isolation.</strong>
ארכיטקטורה
execute_code: await ruby.browser.navigate('https://...')
│
▼
┌──────────────────────┐
│ BrowserPoolManager │
│ (Server-Side) │
│ │
│ Worker 1 (Tenant A) │ ← Docker Container
│ Worker 2 (Tenant B) │ ← Docker Container
│ Worker 3 (free) │
└──────────┬───────────┘
│ Playwright commands
▼
┌──────────────────────┐
│ VisionFallback │ ← GPT-4o Vision
│ (no-DOM fallback) │ כשאין DOM זמין
└──────────────────────┘
מבנה קבצים
/root/browser-pool/
├── pool-manager.ts ← ניהול Workers
├── browser-worker.ts ← Playwright Worker יחיד
├── vision-action.ts ← Vision fallback
├── task-queue.ts ← תור משימות אסינכרוני
├── Dockerfile ← Container per worker
└── docker-compose.yml ← 5 workers מקסימום
חוזה API
// pool-manager.ts
interface BrowserTask {
id: string;
tenantId: string;
action: 'navigate' | 'click' | 'fill' | 'extract' | 'screenshot';
params: Record<string, any>;
timeout: number; // default 30s
useVision: boolean; // fallback ל-GPT Vision
}
interface BrowserResult {
success: boolean;
data?: any;
screenshot?: string; // base64, אם useVision=true
error?: string;
}
class BrowserPoolManager {
async execute(task: BrowserTask): Promise<BrowserResult>;
async getWorkerStatus(): Promise<WorkerStatus[]>;
async releaseWorker(tenantId: string): Promise<void>;
}
// הרחבת ruby SDK ב-Code Mode:
ruby.browser = {
navigate: (url: string) => pool.execute({ action: 'navigate', params: { url } }),
click: (selector: string) => pool.execute({ action: 'click', params: { selector } }),
fill: (fields: Record<string, string>) => pool.execute({ action: 'fill', params: { fields } }),
extract: (schema: object) => pool.execute({ action: 'extract', params: { schema } }),
screenshot: () => pool.execute({ action: 'screenshot', useVision: true })
}
Acceptance Criteria
- [ ] ניתן להריץ Browser task ב-Server בלי Chrome Extension פתוח
- [ ] כל Tenant מקבל Container מבודד (לא רואה session של tenant אחר)
- [ ] Timeout 30s ב-default, מוחזרת שגיאה נקייה
- [ ] Vision fallback פועל כש-DOM חסום (anti-bot)
- [ ] מקסימום 5 workers מקביליים, תור FIFO כשעמוס
GAP-06: Async Task State Graph
מה זה ולמה זה חשוב
כרגע אין מנגנון למעקב אחר משימות ארוכות (המתנה לנציג, polling לאתר, המתנה לתשובת אדם). Agent מתחיל משימה ו"שוכח" אותה.
ארכיטקטורה
States:
queued → executing → waiting_for_external → done
└→ waiting_for_user → done
└→ failed
Events שמעירים State:
- Webhook חיצוני (האתר עדכן סטטוס)
- תגובת המשתמש ב-WhatsApp
- Cron check (polling כל X דקות)
חוזה API
// task-state-graph.ts
type TaskState = 'queued' | 'executing' | 'waiting_for_external'
| 'waiting_for_user' | 'done' | 'failed';
interface AsyncTask {
id: string;
tenantId: string;
conversationId: string;
state: TaskState;
goal: string; // "הזמן שולחן ב-פינטי לשישי"
context: Record<string, any>;
wakeupTrigger?: {
type: 'webhook' | 'cron' | 'user_reply';
value: string; // webhook path / cron expr / "yes|no"
};
createdAt: Date;
updatedAt: Date;
}
class TaskStateGraph {
async create(task: Omit<AsyncTask, 'id' | 'createdAt' | 'updatedAt'>): Promise<string>;
async transition(taskId: string, newState: TaskState, data?: any): Promise<void>;
async wakeup(taskId: string, trigger: any): Promise<void>; // ממשיך ריצה
async getByConversation(tenantId: string, conversationId: string): Promise<AsyncTask[]>;
}
Acceptance Criteria
- [ ] Task שנוצר ב-"waiting_for_user" מתעורר אוטומטית כשהמשתמש עונה "כן"
- [ ] Task שנוצר ב-"waiting_for_external" מתעורר כשמגיע Webhook
- [ ] Cron job בודק כל 5 דקות Tasks "תקועים" מעל 30 דקות → שולח עדכון למשתמש
- [ ] UI ב-Radiant Dashboard מציג רשימת Tasks פעילים לכל Tenant
🔴 SPRINT 3 — Payments & Security
GAP-02: Virtual Card Generator
מה זה ולמה זה חשוב
Agent מבצע כרגע תשלומים עם פרטי כרטיס אמיתי של המשתמש. <strong>זהו סיכון ביטחוני וחוקי קריטי.</strong>
הפתרון: הנפקת כרטיס וירטואלי <strong>חד-פעמי</strong> מוגבל לסכום המדויק שאושר.
ארכיטקטורה
User approves: "כן, שלם 240₪"
│
▼
┌─────────────────────┐
│ VirtualCardVault │
│ ───────────────── │
│ issueCard(240) │ → Stripe Issuing API
│ → cardNumber (tmp) │
│ → expiry (24h) │
│ → cvv │
└──────────┬──────────┘
│
▼
BrowserPool fills
checkout form with
virtual card details
│
▼
┌─────────────────────┐
│ revokeCard() │ → מבוטל מיד אחרי שימוש
└─────────────────────┘
חוזה API
// virtual-card-vault.ts
interface VirtualCard {
id: string;
tenantId: string;
taskId: string;
number: string; // PAN — מוצפן at rest
expiry: string; // MM/YY
cvv: string; // מוצפן
limit: number; // בדיוק הסכום שאושר (בשקלים)
currency: 'ILS' | 'USD' | 'EUR';
status: 'active' | 'used' | 'revoked';
merchantLock?: string; // optional: נעול לספק ספציפי
expiresAt: Date; // default: 24h
}
class VirtualCardVault {
async issue(params: {
tenantId: string;
taskId: string;
amount: number;
currency: string;
merchantLock?: string;
}): Promise<VirtualCard>;
async revoke(cardId: string): Promise<void>;
async getStatus(cardId: string): Promise<VirtualCard>;
}
// שילוב ב-Code Mode SDK:
// ruby.payments.issueVirtualCard({ amount: 240, currency: 'ILS' })
// ruby.payments.revokeCard(cardId)
Acceptance Criteria
- [ ] כרטיס מונפק רק **אחרי** אישור מפורש מהמשתמש (מחובר ל-GAP-03)
- [ ] כרטיס מוגבל לסכום שאושר בדיוק (לא ₪ אחד מעבר)
- [ ] כרטיס מבוטל אוטומטית תוך 24h גם אם לא נעשה בו שימוש
- [ ] פרטי הכרטיס **אינם** נשמרים ב-Logs (masked למעט 4 ספרות אחרונות)
- [ ] Agent לא יכול לגשת לכרטיס האמיתי של המשתמש בשום מקרה
GAP-07: Zero-Knowledge Vault Proxy
מה זה ולמה זה חשוב
כרגע ה-Agent מקבל ב-runtime את ה-API Key/OAuth token של המשתמש ישירות לתוך ה-Code Sandbox — <strong>המודל "רואה" את הטוקן הגולמי.</strong>
<strong>הפתרון:</strong> Agent עובד עם Reference ID, לא עם הטוקן עצמו.
ארכיטקטורה
Agent code:
await ruby.crm.execute({ vaultRef: 'hubspot-tenant-a' })
│
▼ (Agent לא רואה token)
┌────────────────┐
│ Vault Proxy │
│ resolves ref │ → מוציא token מה-Vault (AES-256)
│ calls API │ → שולח request עם token
│ returns data │ → מחזיר data בלבד (לא token)
└────────────────┘
חוזה API
// vault-proxy.ts
// במקום: ruby.gmail.send({ apiKey: 'ya29.a0...' })
// בעתיד: ruby.gmail.send({ vaultRef: 'gmail-mozez-main' })
interface VaultProxyRequest {
vaultRef: string; // ID ב-credential vault
service: string; // 'gmail' | 'hubspot' | ...
action: string;
params: Record<string, any>;
tenantId: string; // מ-auth בלבד
}
class VaultProxy {
async execute(req: VaultProxyRequest): Promise<any> {
const credential = await vault.resolve(req.vaultRef, req.tenantId);
// credential לעולם לא חוזר למודל!
return await serviceAdapters[req.service].call(credential, req.action, req.params);
}
}
Acceptance Criteria
- [ ] ה-API token לא מופיע ב-Sandbox runtime (לא ב-logs, לא ב-context)
- [ ] Agent מקבל רק `vaultRef` — ID אטום
- [ ] Vault Proxy מוודא שה-`tenantId` של ה-ref תואם ל-auth
🟡 SPRINT 4 — Voice & Calling
GAP-01: Audio Pipeline (STT + TTS + IVR)
מה זה ולמה זה חשוב
אין לנו <strong>שום</strong> יכולת קולית. Instinct מנהלים שיחות טלפון מלאות: Agent מקשיב, מבין, מגיב בטבעיות.
ארכיטקטורה
Incoming Call (Twilio)
│
▼
┌──────────────┐
│ STT Engine │ → Deepgram Streaming (Real-time)
│ (Whisper / │ latency < 500ms
│ Deepgram) │
└──────┬───────┘
│ text
▼
Radiant Orchestrator (LLM)
│ response text
▼
┌──────────────┐
│ TTS Engine │ → ElevenLabs / Cartesia
│ Low-latency │ latency < 800ms
└──────┬───────┘
│ audio stream
▼
Twilio plays back
מבנה קבצים
/root/radiant/src/lib/voice/
├── telephony-channel.ts ← Twilio Webhook handler
├── stt-adapter.ts ← Deepgram / Whisper STT
├── tts-adapter.ts ← ElevenLabs / Cartesia TTS
├── ivr-navigator.ts ← ניווט תפריטי טלפון
└── call-session.ts ← ניהול מצב שיחה
חוזה API
// telephony-channel.ts
interface CallSession {
callId: string;
tenantId: string;
from: string; // מספר מחייג
to: string; // מספר שנחייג
direction: 'inbound' | 'outbound';
state: 'ringing' | 'active' | 'ivr_nav' | 'hold' | 'ended';
transcript: TranscriptEntry[];
}
// ivr-navigator.ts
class IVRNavigator {
async detectMenu(audioBuffer: Buffer): Promise<IVRMenu>;
// { options: [{ digit: '1', description: 'הזמנות' }] }
async pressDigit(digit: string): Promise<void>;
async waitForHuman(maxWaitMs: number): Promise<boolean>;
async sayToAgent(text: string): Promise<void>; // TTS → Twilio
}
Acceptance Criteria
- [ ] שיחה נכנסת נתפסת ומתומללת ב-STT תוך < 500ms לחזרת תגובה ראשונה
- [ ] תגובת Agent הופכת לאודיו טבעי (TTS) תוך < 800ms
- [ ] IVR Navigation: Agent לוחץ על "1" כשמוצג תפריט
- [ ] שיחה יוצאת: Agent מחייג מסעדה, מנהל שיחה, ומחזיר סיכום בטקסט
GAP-08: Agentic Outbound Calling
מה זה ולמה זה חשוב
Agent צריך לחייג עסקים שאין להם API (מסעדות, מכוני יופי, בתי מלון קטנים).
חוזה API
// ב-Code Mode SDK:
ruby.voice = {
call: async (params: {
to: string; // מספר טלפון
goal: string; // "תזמין שולחן ל-4 ב-שישי ב-20:00"
maxDurationMin: number; // default 5
language: 'he' | 'en';
}) => Promise<CallResult>,
// CallResult:
// { success, summary, reservation?: {...}, recordingUrl? }
}
Acceptance Criteria
- [ ] Agent מחייג מספר טלפון, מנהל שיחה, ומחזיר summary בעברית
- [ ] אם נציג לא עונה תוך 2 דקות → מסיים, מדווח למשתמש
- [ ] תמלול השיחה המלא נשמר ב-Call Session ב-DB
🟢 פערים קלים (לאחר Sprint 4)
GAP-09: Confirmation Engine — Rich Cards
WhatsApp Interactive Buttons:
[ ✅ כן, אשר ] [ ✏️ ערוך ] [ ❌ בטל ]
- מחובר ל-TaskStateGraph (GAP-06)
- כפתור "כן" → מפעיל continuation של ה-Task
- כפתור "ערוך" → פותח dialog עריכה
GAP-10: SMS & iMessage Channels
- Twilio SMS Webhook → אותו MessageNormalizer (GAP-05)
- Apple Business Chat Webhook → אותו Normalizer
- שום שינוי ב-Orchestrator — רק Adapter נוסף
📊 סיכום תוכנית הספרינטים
| Sprint | שבועות | GAPs | תוצר |
|---|---|---|---|
| **Sprint 1** | 1–2 | GAP-03 + GAP-05 | Safety Layer + Message Normalizer |
| **Sprint 2** | 3–4 | GAP-04 + GAP-06 | Browser Pool + Async Tasks |
| **Sprint 3** | 5–6 | GAP-02 + GAP-07 | Virtual Cards + Vault Proxy |
| **Sprint 4** | 7–8 | GAP-01 + GAP-08 | Voice Pipeline + Outbound Calling |
| **Backlog** | — | GAP-09 + GAP-10 | Rich Cards + SMS/iMessage |
📁 סביבת הפיתוח המומלצת
VPS: 84.247.162.143
├── /root/radiant/src/lib/safety/ ← Sprint 1: Interceptor
├── /root/radiant/src/lib/messaging/ ← Sprint 1: Normalizer
├── /root/browser-pool/ ← Sprint 2: Browser Pool
├── /root/radiant/src/lib/tasks/ ← Sprint 2: State Graph
├── /root/radiant/src/lib/payments/ ← Sprint 3: Virtual Cards
├── /root/radiant/src/lib/vault/ ← Sprint 3: Vault Proxy
└── /root/radiant/src/lib/voice/ ← Sprint 4: Audio Pipeline
*מסמך זה מנוהל ב-<code>/root/.openclaw-shared/docs/</code> ומשתקף באתר <code>doc.turqizai.com</code>.*
*כל שינוי בסטטוס יש לעדכן דרך <code>./logs.sh stage <gap-id> <done|doing|todo></code>.*
מפת MCP מלאה
מפת MCP מלאה — Radiant / Ruby
<strong>תאריך:</strong> 22 באוגוסט 2026 (עודכן 25 באוגוסט 2026)
<strong>מטרה:</strong> מפה אחידה של כל רכיבי ה-MCP במערכת — מה חשוף, דרך איזה transport, ולמי.
**עדכון 25.8.26:** הקטלוג אוחד לקובץ אחד — `integration-templates.ts` (5501 אינטגרציות). `pieces-catalog.ts` ו-`unified-catalog.ts` נמחקו. ראה `unified-catalog.md`.
1. שרת MCP מוטמע (Option 2) — radiant-apibank
השרת המרכזי שמחבר את OpenClaw/Radiant ל-api-bank. רץ STDIO בתוך api-bank, מדבר ישירות עם ה-SDK.
| כלי | פעולה | tenantId | אימות |
|---|---|---|---|
| `search_tools` | חיפוש integrations | — (ציבורי) | — |
| `execute_code` | הפעלת action | מ-auth | `x-api-key` |
| `list_available_actions` | מה מחובר ל-tenant | מ-auth | `x-api-key` |
| `gateway_status` | סטטוס חיבור | מ-auth | `x-api-key` |
| `list_templates` | רשימת templates | — | — |
| `get_template` | פרטי אינטגרציה + actions | — | — |
| `test_integration` | הרצה sandbox (mock) | מ-auth | `x-api-key` + `x-sandbox` |
| `manage_vault` | ניהול סודות | פרמטר | VAULT_MASTER_KEY |
| `federation_connections` | חיבורי federation | — | — |
<strong>רישום OpenClaw:</strong> <code>mcp.servers.radiant-apibank</code> → <code>npx tsx src/mcp-serve.ts</code> (cwd=<code>/root/.openclaw/workspace/turqiz-ai/api-bank</code>).
2. נקודת MCP היסטורית — /api/mcp/convert (כיוון הפוך)
<code>POST /api/mcp/convert</code> (api-bank) — <strong>מייבא</strong> config של שרת MCP חיצוני (<code>mcpServers</code> / <code>name+tools</code>) והופך אותו ל-RFB integration (<code>rfb-mcp-*</code>) + Ruby talent (<code>talent-mcp-*</code>).
- זה הכיוון **ההפוך** ממה שרצינו: הוא מביא MCP חיצוני פנימה, לא חושף את api-bank החוצה.
- קלט: JSON `{ mcpConfig, customName, customCategory }` או multipart (קובץ).
- פלט: `{ success, rfb, talent, endpointsCount }`.
- אחסון: `data/custom_rfb.json` + `data/custom_talents.json`.
3. מפת ה-API המלאה של api-bank (REST — הבסיס ל-MCP)
ה-MCP המוטמע יושב על השכבה הזו (SDK ישיר, לא HTTP). למען התיעוד — הנה כל ה-endpoints:
ליבה (SDK / Gateway)
| Endpoint | Method | מה עושה |
|---|---|---|
| `/api/gateway` | POST | execute מאוחד (action→integration) |
| `/api/gateway` | GET | סטטוס / `?path=actions` |
| `/api/gateway/batch` | POST | מרובה פעולות |
| `/api/gateway/pipeline` | POST | שרשרת פעולות |
| `/api/gateway/docs` | GET | תיעוד אוטומטי |
| `/api/gateway/logs` | GET | לוגים + metrics |
| `/api/gateway/webhooks` | POST | ניהול webhooks |
| `/api/execute` | POST | SDK ישיר (integrationSlug+action+params) |
| `/api/search` | GET | חיפוש templates |
| `/api/manifests/execute` | POST | ביצוע manifest |
| `/api/manifests/validate` | POST | ולידציית manifest |
Templates (Marketplace)
| Endpoint | Method |
|---|---|
| `/api/templates` | GET |
| `/api/templates/[slug]` | GET |
| `/api/templates/[slug]/actions` | GET |
| `/api/templates/[slug]/events` | GET |
| `/api/templates/[slug]/execute` | POST |
| `/api/templates/[slug]/test` | POST |
| `/api/templates/[slug]/fork` | POST |
| `/api/templates/[slug]/install` | POST |
| `/api/templates/[slug]/star` | POST |
| `/api/categories` | GET |
Federation
| Endpoint | Method |
|---|---|
| `/api/federation/connections` | GET/POST |
| `/api/federation/connections/[id]` | GET |
| `/api/federation/connections/[id]/execute` | POST |
| `/api/federation/connections/[id]/discover` | POST |
| `/api/federation/chains` | GET/POST |
| `/api/federation/chains/[id]/execute` | POST |
Gateway (connections/triggers/webhooks)
| Endpoint | Method |
|---|---|
| `/api/gateway/connections` | GET/POST |
| `/api/gateway/connections/[id]` | GET |
| `/api/gateway/federation` | GET/POST |
| `/api/gateway/federation/[id]` | GET |
| `/api/gateway/triggers` | GET/POST |
| `/api/gateway/webhooks/[webhookId]` | GET |
Vault
| Endpoint | Method |
|---|---|
| `/api/vault/store` | POST |
| `/api/vault/keys` | GET |
| `/api/vault/keys/[id]` | DELETE |
Talent / Identity / AI
| Endpoint | Method |
|---|---|
| `/api/talents` | GET/POST |
| `/api/talents/chat` | POST |
| `/api/talents/import` | POST |
| `/api/identities` | GET/POST |
| `/api/identities/chat` | POST |
| `/api/ai/autofill-wizard` | POST |
| `/api/rfb` | GET/POST |
| `/api/seed` | GET |
4. שכבת ה-SDK + Code Mode (מה שה-MCP קורא ישירות)
| רכיב | מיקום | תפקיד |
|---|---|---|
| `TurqizAPIBank` | `lib/api-bank/sdk.ts` | SDK ראשי (execute/connect/vault/manifest) |
| `IntegrationClient` | `lib/api-bank/sdk.ts` | client טיפוסי לאינטגרציה |
| `VaultClient` / `ManifestClient` | `lib/api-bank/sdk.ts` | vault + manifest |
| `ActionRouter` | `lib/api-bank/action-router.ts` | action→integration+rcpAction, auth, rate-limit |
| `executeAction` | `lib/api-bank/rcp-translator.ts` | מנוע ביצוע (retry/backoff) |
| `ApiBankEngine` | `lib/api-bank/engine.ts` | templates CRUD + search |
| `sandboxEngine` | `lib/api-bank/sandbox-engine.ts` | mock executions |
| `runCodeMode` | `lib/api-bank/code-mode.ts` | **Code Mode אמיתי (23.8)** — הרצת JS של המודל ב-node:vm מבודד + timeout; חושף ruby.search/execute/get/list; endpoint POST /api/codemode |
| `key-vault` | `lib/api-bank/key-vault.ts` | store/get/list/delete/rotate (AES) |
| `pipeline-engine` / `rate-limiter` / `task-queue` / `observability-engine` | `lib/api-bank/` | שרשרת / הגבלת קצב / תור משימות / מדידה |
5. צרכני MCP
| צרכן | איך צורך | סטטוס |
|---|---|---|
| OpenClaw / Radiant (port 18790) | `mcp.servers.radiant-apibank` (stdio) | ✅ רשום + probed |
| Claude Code / Cursor (חיצוני) | דרך `openclaw mcp serve` / url | מתוכנן |
Registry פנימי
Registry פנימי (Self-hosted) — Radiant
<strong>תאריך:</strong> 22 באוגוסט 2026
<strong>החלטה:</strong> ✅ registry פנימי self-hosted (לא מסתמך על ה-MCP Registry הציבורי).
רציונל
- שליטה מלאה (מתאים לראיית multi-tenant: מי רואה מה, per-tenant isolation).
- לא חושף IP פנימי / creds לרגיסטרי ציבורי.
- Controlled publish — כמו Intent Discovery: שום דבר לא מתפרסם בלי אישור admin/operator.
ארכיטקטורה
בנוי על המודל הקיים <code>IntegrationTemplate</code> (כבר יש <code>visibility</code> public/private/unlisted, <code>authorId</code>, <code>tenantId</code>, <code>version</code>, <code>stars</code>, <code>installs</code>, <code>verified</code>) + אוסף ייעודי <code>apibank_registry_entries</code>.
| רכיב | מיקום | תפקיד |
|---|---|---|
| `RegistryEngine` | `src/lib/api-bank/registry-engine.ts` | submit/review/publish/revoke/list/get/resolve |
| MCP tools | `mcp/server.ts` (3 כלים חדשים) | registry_search / registry_publish / registry_review |
| Route REST | `src/app/api/registry/route.ts` | GET list / POST submit / review / publish |
Namespace בעל שם
- `io.<tenant>/<server>` — למשל `io.default/radiant-apibank`.
- `me.<domain>/<server>` — אם רוצים להצמיד ל-domain (בעלות DNS).
- `canonicalName(namespace, name)` = `${namespace}/${name}`.
זרימת פרסום (Controlled)
submit (pending) ──► review (approve|reject, operator) ──► publish (live)
│
└── reject/revoke
- `registry_publish` — כל אחד (LLM/tenant) יכול submit → נכנס `pending`.
- `registry_review` — **דורש operator auth** (`APIBANK_API_KEY`/`RADIANT_API_KEY` ב-env). בלי המפתח = נחסם (`401`-style guard).
- `publish` — מעביר `approved`→`live` ומסמן את ה-template המשויך כ-`public`.
MCP tools (נוספו 3 — סה"כ 12 כלים)
| כלי | פעולה | אימות |
|---|---|---|
| `registry_search` | חיפוש registry (query/scope/state) | — |
| `registry_publish` | submit לפרסום (pending) | tenant (authorId) |
| `registry_review` | approve/reject | **operator only** (GATEWAY_API_KEY) |
| `registry_install` | התקנה לתוך tenant (integration→installTemplate; mcp→RFB+talent) | tenant |
REST endpoints
| Endpoint | Method | מה עושה |
|---|---|---|
| `/api/registry` | GET | רשימה/חיפוש (`s`, `scope`, `state`, `tenantId`, `limit`) |
| `/api/registry` | POST | submit (pending) |
| `/api/registry/review` | POST | approve/reject (operator, `x-api-key`) |
| `/api/registry/publish` | POST | pending→live (operator) |
| `/api/registry/install` | POST | התקנה לתוך tenant |
אימות (verified 2026-08-22)
- `tsc --noEmit` — clean.
- `registry_publish` → יצר entry `pending`.
- `registry_review` בלי מפתח operator → **נחסם** ("requires operator auth").
- `registry_review` עם `APIBANK_API_KEY` → `approved` (עם reviewerId + reviewNote).
- `openclaw mcp probe radiant-apibank --json` → **12 tools** גלויים ל-LLM.
- test entry נוקה מ-Mongo.
הצעד הבא (לא ממומש עדיין)
- ~~`resolve` → חיבור registry entry ל-install/import בפועל~~ ✅ **מומש (2026-08-22)**: `registry_install` + `RegistryEngine.install()`.
- ~~Integration עם `/api/mcp/convert`~~ ✅ **מומש (2026-08-22)**: registry entry מסוג `mcp` מותמר אוטומטית ל-RFB + talent (scoped per-tenant) דרך `convertMcpToRfb`.
מימוש install / mcp-convert (הושלם)
- `RegistryEngine.install(name, tenantId, authConfig?)`:
- `integration`/`talent` + templateSlug → `apiBankEngine.installTemplate(...)`.
- `mcp` → `extractMcpFromEntry` + `convertMcpToRfb` (כתיבה scoped ל-tenant ל-`custom_rfb.json` + `custom_talents.json`).
- MCP tool **`registry_install`** + REST `POST /api/registry/install`.
- אומת E2E: publish→review→install → `{success:true, rfbSlug:"rfb-demo-mcp"}`, ו-RFB נכתב ל-`custom_rfb.json`.
- test entries נוקו (השארתי את rfb-filesystem-mcp + rfb-brave-web-search-mcp הקיימים).
מראת ה-registry הציבורי
מראת הרגיסטרי הציבורי של MCP (Public Registry Mirror)
<strong>תאריך:</strong> 22 באוגוסט 2026
<strong>החלטה:</strong> ✅ <strong>אפשרות ג (Hybrid)</strong> — mirror של metadata + import on-demand של server.json מלא.
הבעיה שנפתרה
ה-<code>https://registry.modelcontextprotocol.io</code> הוא הרגיסטרי הציבורי הרשמי של MCP — מאכלס <strong>20,000+ שרתי MCP</strong>. השאלה הייתה: "האם כל האלפים כבר נתפסו אצלנו?" — <strong>לא</strong>. היינו עם 3 רשומות פנימיות בלבד.
הגישה (Hybrid — אפשרות ג)
| שכבה | מה | אחסון |
|---|---|---|
| **Mirror metadata** | name/description/version/transports/tags/repository של כל השרתים | `apibank_public_mcp` |
| **Import on-demand** | server.json מלא (packages/remotes) רק כשמתקינים בפועל | `fullJson` באותה רשומה |
מה לא עשינו (ולמה)
- **לא scraping של ה-HTML** של האתר — הוא SPA ריק. יש **API נקי** (`/v0.1/servers`).
- **לא mirror של ה-server.json המלא** — זה היה מושך GBs מיותרים. מושכים metadata לחיפוש + full json שכשצריך.
ה-API הציבורי (OpenAPI v0.1)
| Endpoint | מה מחזיר |
|---|---|
| `GET /v0.1/servers?page_size=N&cursor=...` | `{servers:[{server,_meta}], metadata:{count,nextCursor}}` |
| `GET /v0.1/servers/{name}/versions/{version}` | server.json מלא |
| `POST /v0.1/publish` | פרסום (GitHub OAuth / domain ownership) |
כל שרת = <code>server.json</code>: <code>name</code> (reverse-DNS), <code>description</code>, <code>version</code>, <code>packages[]</code> (npm/pypi/cargo/oci), <code>remotes[]</code> (stdio/streamable-http/sse), <code>repository</code>, <code>_meta.status</code> (active/deprecated/deleted), <code>_meta.isLatest</code>.
רכיבים שנבנו
`src/lib/api-bank/public-registry.ts`
- `mirrorPublicRegistry()` — פגינוציה מלאה על `/v0.1/servers`, upsert ל-Mongo, `latestOnly` (לסנן גרסאות ישנות).
- `searchPublicMcp()` — חיפוש במראה (query/name/description/title/tags) + סינון `tag`/`namespace`/`status`.
- `getPublicServer()` / `importFullServerJson()` / `countPublicMcp()`.
- `classify()` — תיוג סמנטי ל-16 קטגוריות (dev-tools, web-search, database, filesystem, finance, media, ai-llm, productivity, geo-location, security, cloud-infra, ecommerce, health, education, integration, misc).
MCP tools (נוספו 3 — סה"כ 16 כלים)
| כלי | פעולה |
|---|---|
| `public_mcp_search` | חיפוש במראה (query/tag/namespace/status) |
| `public_mcp_mirror` | משוך/רענן את המראה (פגינוציה) |
| `public_mcp_import` | import on-demand של server.json מלא |
Script
- `src/scripts/mirror-run.ts` — npm script `mirror` (טוען .env.local, רץ mirror מלא).
אימות (2026-08-22)
- `tsc --noEmit` — clean.
- `public_mcp_mirror(maxPages=2)` → 35 שרתים נמשכו (עמודים ראשונים).
- `public_mcp_search(query="ai")` + `(tag="finance")` → תוצאות אמיתיות.
- **Full mirror** (bg) → **22,700+ שרתים** נמשכו (עדיין רץ; מונה חי).
בטיחות / controlled
- שום דבר לא נכנס `live` אוטומטית — הכל `importState: queued`.
- אישור/התקנה → דרך ה-flow הקיים (`registry_install` / admin approval).
- `latestOnly` ברירת מחדל = לא מציפים גרסאות כפולות.
הצעד הבא
- ✅ לחבר `public_mcp_import` → `registry_install` אוטומטית: שרת ציבורי שאושר יתורגם ל-RFB+talent אצלנו.
- ✅ cron/refresh ל-mirror — `public-mcp-mirror-refresh` (יומי 04:30 Berlin, isolated agentTurn).
השלמה (2026-08-22 15:40+)
<strong>חיבור מלא public → install נבנה ואומת:</strong>
- `registryEngine.installPublic(name, tenantId)` — בונה MCP connection config אמיתי מ-server.json ציבורי (לא RFB מזויף):
- `remotes[streamable-http]` → `{ url, transport: 'streamable-http' }`
- `packages[npm]` → `{ command: 'npx', args: ['-y', <id>] }`
- `packages[pypi]` → `{ command: 'uvx', args: [<id>] }`
- `buildMcpServerConfig()` — ממיר packages/remotes → OpenClaw `mcp.servers` shape.
- `materializePublicRfb()` — RFB light (point-to-remote execute-tool, tools מתגלים live). slug מנורמל מהשם המלא (`rfb-ai-com-mcp-strava`).
- MCP tool חדש: `registry_install_public` → סה"כ **17 כלים**.
<strong>אימות E2E:</strong>
- `registry_install_public('ai.contextstudios/mcp')` → streamable-http config ✅
- `registry_install_public('ai.cueapi/mcp')` → `npx -y @cueapi/mcp` ✅
- הרדמה מלאה: `openclaw mcp set public-strava` + `probe` → **13 tools אמיתיים** התגלו live (`exploreSegments`, `getClubActivitiesById`, ...) ✅
- artifacts בדיקה נוקו; RPBs לגיטימיים (`rfb-filesystem-mcp`, `rfb-brave-web-search-mcp`) נשמרו ✅
<strong>הבנה מרכזית:</strong> ה-server.json הציבורי לא מכיל רשימת tools — הוא מתאר packages (npm/pypi) + remotes. tools מתגלים רק בזמן ריצה (probe/live). לכן החיבור הנכון = MCP connection config → <code>openclaw mcp add</code>, לא RFB עם כלים מזויפים.
<strong>cron:</strong> <code>public-mcp-mirror-refresh</code> — יומי 04:30 Berlin (isolated agentTurn).
Controlled-publish על שרתים ציבוריים (15:50+ GMT+2)
<strong>החלטה</strong> (המשתמש: "כן"): שרת ציבורי לא ניתן להתקנה ישירה — חייב לעבור <code>submit(default pending) → review(approve) → publish(live)</code>.
- `PublicMcpDoc.publishState`: `pending(default) → approved → live / rejected` (בדומה ל-registry הפנימי).
- `reviewPublic(name, decision, reviewerId, note)` + `publishPublic(name)` ב-public-registry.ts.
- `installPublic` חסום אלא אם `publishState ∈ {approved, live}` — אחרת `error: not live (publishState=...)`.
- **backfill**: 24,183 רשומות קיימות קיבלו `publishState: pending` (שום דבר לא אושר אוטומטית).
- **re-mirror בטוח**: `$setOnInsert` שומר אישור קיים — רענון mirror לא יאפס שרת שאושר.
- MCP tools חדשים (operator-gated, דורש APIBANK_API_KEY/RADIANT_API_KEY):
- `public_mcp_review(name, decision, reviewerId?, note?)`
- `public_mcp_publish(name)`
→ סה"כ <strong>19 MCP tools</strong>.
<strong>אימות E2E:</strong>
- install בלי אישור → חסום (`not live`) ✅
- review בלי key → חסום (`requires operator auth`) ✅
- review(approve) → approved ✅
- publish → live ✅
- install → הצלחה (rfbSlug + mcpServer) ✅
- state reset + RFB test artifacts נוקו; legit RFBs נשמרו ✅
RCP Data Layer (PostgreSQL + RLS)
RCP Data Layer — PostgreSQL + RLS
מומש + מאומת **2026-08-22**. החלטת DB נסגרה: PostgreSQL 16 + Row-Level Security.
החלטה
בחירת DB: <strong>PostgreSQL 16 + RLS</strong> (אושר ע"י Mozez).
נימוק: בידוד טננטים ברמת ה-DB, PCI/ACID, control plane. Redis ל-cache/sessions. MongoDB ל-legacy עד מיגרציה.
עקרון הבידוד (anti-spoofing)
כל רשומה חייבת <code>tenant_id</code>. הערך מגיע <strong>מ-auth context, לא מהלקוח</strong>:
SET app.current_tenant_id = '<tenantId>'; -- בכל חיבור/טרנזקציה
-- RLS מסנן כל שאילתה לפי tenant_id = rcp_current_tenant()
-- בלי SET — רואים אפס רשומות (אין דליפה)
סכמת ה-DB (11 טבלאות — כולן RLS-enabled)
| קבוצה | טבלאות |
|---|---|
| Core | `tenants` · `tenant_enrollments` · `tenant_nodes` |
| CRM | `leads` · `conversations` |
| Calendar | `appointments` |
| Federation | `connection_registry` · `federation_log` |
| Events | `event_subscriptions` |
| Discovery | `intent_discovery` |
| Analytics | `analytics_events` |
פונקציות עזר
rcp_current_tenant() -- בסיס ה-RLS (קורא app.current_tenant_id)
create_tenant(id, name, plan, workspace) -- idempotent
issue_enrollment(tenant_id, token, ttl) -- token חד-פעמי
consume_enrollment(token) -- צריכה + בדיקת פג תוקף
Roles + אבטחה
- `rcp_app` — role אפליקציה, מחויב RLS, מקבע tenant בכניסה.
- `rcp_platform_admin` — `BYPASSRLS`, עוקף RLS (control-plane בלבד).
- `pgcrypto` — `gen_random_uuid()` עבור מזהים.
קוד — Intent Router (src/rcp/)
מימוש <code>route(tenantId, intent, payload)</code> tenant-scoped. compile verified (<code>tsc --noEmit</code> EXIT 0).
- `types.ts` — RCPIntent, RCPMessage, Envelope, Payload (tenantId מנדטורי)
- `db.ts` — Pool + withTenant() + tenantExists() (אכיפת RLS)
- `router.ts` — route() + 44-intent mapping + audit federation_log
- `discovery.ts` — discover() (שלב 4, DETECT→PROPOSE→STAGE→ROUTE→PROMOTE)
<strong>handlers ממומשים:</strong> <code>create_lead</code>, <code>list_leads</code>, <code>update_lead</code>, <code>get_conversations</code>, <code>book_appointment</code>, <code>analytics</code>, <code>create_connection</code>, <code>get_status</code>, <code>greet</code>, <code>configure</code>. שאר ה-intents → escape hatch לכלי OpenClaw/חיצוני.
Intent Discovery (שלב 4)
מנגנון גילוי intents חדשים on-the-fly, tenant-scoped:
| שלב | פונקציה | תיאור |
|---|---|---|
| 1 DETECT | `translate()` | keyword-map → intent + confidence |
| 2 PROPOSE | `propose()` | name + schema + hints + tool |
| 3 STAGE | `stage()` | שמירה כ-pending ב-intent_discovery (RLS) |
| 4 ROUTE | `routeNearest()` | מיפוי לכלי/ערוץ הכי קרוב |
| 5 PROMOTE | `promote()` | אישור/דחייה/merge ע"י platform_admin |
כללי בטיחות: dedup (similarity ≥ 0.82 → merge), rate-limit (MAX_PENDING=10), audit ב-federation_log, tenantId מ-auth context, אין קידום ל-enum בלי platform_admin.
הבא בתור
- חיבור `src/rcp` ל-runtime (API endpoint / ערוצי תקשורת).
- שאלות פתוחות: external-adapters layer, `send_email` via Gmail/SMTP, gateway-per-tenant.
ערוצים → רובי → Radiant (סגירת הלולאה)
חיבור ערוצים → רובי → Radiant (סגירת הלולאה)
נכתב: 2026-09-01 | סטטוס: ✅ נבנה (3 קבצים) + ממתין ל-restart
הבעיה שנמצאה
<strong>ווצאפ (פורט 3090) לא מחובר לרובי.</strong> בדקתי את כל קבצי ה-gateway
(<code>server_gateway_v20.js</code>, <code>server_gateway_v21.js</code>, <code>server.ts</code>, <code>server.js</code>).
<strong>גילוי קריטי:</strong> הקובץ שרץ בפועל הוא <code>server.js</code> (40KB), לא <code>server_gateway_v21.js</code>
(12KB). ה-<code>server.js</code> כבר מחובר ל-Radiant — אבל <strong>בצורה הפוכה מהעיקרון</strong>:
הוא שולח ישירות ל-Radiant (<code>model: 'openclaw'</code>) כראשי, ורובי רק כ-fallback.
זה ה-F-16 (מנוע בסיסי) בלי ההגדרות של רובי.
העיקרון (החלטה)
<strong>הכל עובר דרך רובי.</strong> רובי הוא הממשק שמחליף את OpenClaw למשתמשי קצה
(ה-F-16I), ומוסיף את כל ההגדרות: personality, skills, whatsapp rules,
זיכרון, כלים, MCP, אוטומציות.
ווצאפ לא מדבר ישירות עם OpenClaw/Radiant. הוא קורא ל-<code>/api/ruby/chat</code>,
ורובי קורא ל-Radiant Gateway. <strong>רובי ראשי, Radiant fallback.</strong>
הזרימה המלאה
ווצאפ (3090)
↓ 1. שולח לרובי /api/ruby/chat (channel=whatsapp)
רובי (3004)
↓ 2. טוען personality + skills + whatsapp rules + זיכרון של הטננט
↓ 3. קורא ל-Radiant Gateway (18790) → הסוכן openclaw/ruby_master
Radiant (OpenClaw + הגדרות רובי)
↓ 4. הסוכן המלא חושב (עם כל ההקשר)
↓ 5. תשובה חוזרת לרובי
רובי → ווצאפ
↓ 6. שולח תשובה חזרה למספר
פורטים (אומתו בלייב)
| שירות | פורט | סטטוס |
|---|---|---|
| ווצאפ gateway | 3090 | ✅ connected (baileys-v7) |
| רובי (ruby-ai) | 3004 | ✅ רץ |
| Radiant Gateway (OpenClaw) | 18790 | ✅ רץ (HTML "Radiant AI") |
| Ollama | 11434 | ✅ רץ |
מה נבנה (3 קבצים)
1. `ruby-ai/src/models/RubyAgent.ts` — index על whatsappNumber ✅
// אחרי הגדרת ה-schema
RubyAgentSchema.index({ whatsappNumber: 1 }, { sparse: true });
- `sparse: true` — מדלג על agents בלי ווצאפ (חוסך מקום).
- לא `unique` — כי whatsappNumber יכול להיות ריק.
2. `ruby-ai/src/app/api/ruby/agents/route.ts` — whatsappNumber ב-GET ✅
export async function GET(request: NextRequest) {
try {
await connectToDb();
const { searchParams } = new URL(request.url);
const tenantId = sanitizeString(searchParams.get('tenantId'), { maxLength: 100 });
const whatsappNumber = sanitizeString(searchParams.get('whatsappNumber'), { maxLength: 20 });
// נרמול: ה-DB שומר "+972 54-545-4034", ה-gateway שולח "972545454034"
const filter: any = {};
if (whatsappNumber) {
const digits = whatsappNumber.replace(/\D/g, '');
if (digits) {
const pattern = digits.split('').join('[^0-9]*');
filter.whatsappNumber = { $regex: new RegExp(pattern) };
}
} else if (tenantId) {
filter.tenantId = tenantId;
}
const agents = await RubyAgent.find(filter).select('-shopifyToken -crmToken -knowledgeText');
return NextResponse.json({ success: true, agents }, { headers: CORS_HEADERS });
} catch (err: unknown) {
// ...
}
}
<strong>למה regex?</strong> ה-DB שומר <code>+972 54-545-4034</code> (עם רווחים/מקפים/פלוס),
אבל ה-gateway שולח <code>972545454034</code> (נקי). ה-regex מתעלם מתווים לא-ספרתיים
ומאפשר התאמה בין שני הפורמטים. אומת בלייב: ✅ מתאים, ומספר שגוי לא מתאים.
3. `whatsapp-gateway/server.js` — רובי ראשי, Radiant fallback ✅
<strong>הקובץ שרץ בפועל הוא <code>server.js</code> (לא <code>server_gateway_v21.js</code>).</strong>
השינוי: במקום לשלוח ישירות ל-Radiant (<code>model: 'openclaw'</code>), שולחים לרובי
(<code>/api/ruby/chat</code>), ורק אם רובי נכשל — fallback ישיר ל-Radiant.
// ── FORWARD TO RUBY (הכל עובר דרך רובי — F-16I) ──
try {
const rubyUrl = process.env.RUBY_URL || 'http://127.0.0.1:3004';
const systemContext = await getLiveIntegrationsContext();
const rubyRes = await fetch(`${rubyUrl}/api/ruby/chat`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
message: body,
channel: 'whatsapp',
tenantId: 'default',
sessionId: `wa_${jid}`,
userId: remotePhone,
metadata: { phone: remotePhone, name: senderName, systemContext },
}),
});
const rubyData = await rubyRes.json().catch(() => ({}));
const reply = rubyData.reply;
if (reply) {
await sendOutboundMessageOrMedia(jid, reply, isGroup);
// ...
} else {
// fallback ישיר ל-Radiant (model: 'openclaw')
}
} catch (err) {
// fallback ישיר ל-Radiant
}
4. `ruby-ai/src/app/api/ruby/chat/route.ts` — אין צורך בשינוי
כבר תומך ב-<code>channel: 'whatsapp'</code>, <code>tenantId</code>, <code>sessionId</code>, <code>userId</code>, <code>metadata</code>.
נקודות שצריך להחליט / להשלים
1. <strong><code>tenantId</code></strong> — כרגע <code>default</code> קבוע ב-<code>server.js</code>. כדי לפתור לפי מספר ווצאפ,
צריך לחבר את ה-lookup של <code>whatsappNumber</code> (סעיף 2) לתוך <code>server.js</code>.
כרגע ה-lookup נבנה אבל עדיין לא מחובר ל-<code>server.js</code> (שם עדיין <code>default</code>).
2. <strong><code>RUBY_URL</code></strong> — <code>http://127.0.0.1:3004</code> מקומי. אם ה-gateway בקונטיינר נפרד,
לשנות ל-<code>http://ruby-ai:3004</code>.
3. <strong>restart</strong> — צריך restart ל-<code>server.js</code> (3090) ול-ruby-ai (3004) כדי שהשינויים ייכנסו.
קשור ל-RBAC (נבנה קודם)
- `can_edit_source_code` — נוסף ל-3 קבצים (backend + UI).
- `rbac.ts` — מודול מרכזי (api-bank + ruby-ai).
- אכיפה ב-rollout, images, cross-channel-router.
- 15/15 בדיקות עוברות.
אחידות גרסה + מניפסט (Version Manifest)
אחידות גרסה + מניפסט (Version Manifest)
נכתב: 2026-09-01 | סטטוס: ✅ נבנה (מקור אמת יחיד)
העיקרון
<strong>הגרסה שלנו (Radiant) עצמאית.</strong> אנחנו לא תלויים בעדכוני OpenClaw.
OpenClaw הוא רק <strong>רכיב פנימי</strong> בתוך הגרסה שלנו.
Radiant v1.5.0 = {
ruby-ai: v1.5.0 ← שלנו
openclaw: 2026.7.1-2 ← רכיב (עדכון חיצוני)
skills: v1.5.0 ← שלנו
memory: v1.5.0 ← שלנו
}
פורמט המספור
<strong>Semver</strong> (<code>v1.5.0</code>) — כבר בשימוש ב-<code>TenantImage</code>, וזה הסטנדרט.
v<major>.<minor>.<patch>[-<channel>]
v1.5.0 → לייב יציב (stable)
v1.5.0-canary → בדיקה
v1.5.1-dev → פיתוח
מקור אמת יחיד: manifest.json
<strong>קובץ אחד</strong> ב-root של <code>turqiz-ai/</code> מגדיר הכל:
/root/.openclaw/workspace/turqiz-ai/manifest.json
מכיל:
- `current` — הגרסה הנוכחית (stable)
- `devVersion` — גרסת ה-dev
- `releases[]` — היסטוריה מלאה, כל גרסה עם:
- `components` — מניפסט (איזה ruby-ai, openclaw, skills, memory)
- `changelog` — מה השתנה
- `isGoldenMaster` — ברירת מחדל לטננט חדש
- `channel` — stable/canary/dev/legacy
עוזר גישה: lib/version.ts
קיים בשני הפרויקטים (כי tsconfig נפרד):
- `ruby-ai/src/lib/version.ts`
- `api-bank/src/lib/version.ts`
פונקציות:
- `getCurrentVersion()` → `v1.5.0`
- `getDevVersion()` → `v1.5.1-dev`
- `getGoldenMasterVersion()` → `v1.5.0`
- `getComponent('v1.5.0', 'openclaw')` → `2026.7.1-2`
- `getChangelog(version)` → changelog
- `isLatest(version)` → bool
מה עודכן לקרוא מה-manifest
| קובץ | שינוי |
|---|---|
| `ruby-ai/src/app/api/ruby/version/route.ts` | `LATEST_AVAILABLE_VERSION` + `CHANGELOG` מה-manifest |
| `ruby-ai/src/app/api/ruby/tenants/version/route.ts` | אותו דבר (היה כפילות מלאה) |
| `ruby-ai/src/models/Tenant.ts` | `appVersion`/`targetVersion`/`imageTag` default מה-manifest |
| `api-bank/src/app/api/admin/control/rollout/route.ts` | `goldenMaster` fallback מה-manifest |
| `api-bank/src/app/api/admin/control/images/route.ts` | seed מה-manifest + `radiant/tenant` (לא `ruby/tenant`) |
| `ruby-ai/package.json` | `version: 1.5.0` (sync) |
מה עוד נשאר (hardcode שטרם עודכן)
<strong>✅ עודכן בסבב זה:</strong>
- `container/route.ts` — `turqiz/radiant:${getGoldenMasterVersion()}`
- `personalities/route.ts` — `getCurrentVersion()` + `isLatest()`
- `dashboard/personalities/page.tsx` — הסרת hardcode (backend מחליט)
- `admin/tenants/page.tsx` — הסרת hardcode
- `rollout/route.ts` — `getGoldenMasterVersion()` + `getPreviousStableVersion()`
- `version/route.ts` + `tenants/version/route.ts` — rollback מה-manifest
- `extension/ping/route.ts` — `version: getCurrentVersion()` (היה `3.1.0` hardcoded)
<strong>✅ באגים שתוקנו:</strong>
- `Dockerfile.fast` השתמש ב-`/api/ruby/health` שלא קיים (404) → יצרתי `health/route.ts`
- `ping/route.ts` החזיר `version: '3.1.0'` hardcoded → עכשיו מה-manifest
⚠️ פער קריטי: ה-image לא מכיל OpenClaw
בדקתי את <code>turqiz/ruby:v1.5.0</code> (docker run):
- ❌ אין `openclaw` binary
- ❌ אין `.openclaw*` / `openclaw.json`
- ✅ רק Next.js (ruby-ai)
<strong>✅ נבנה הפתרון (3 קבצים):</strong>
1. <code>ruby-ai/Dockerfile.radiant</code> — image חדש: OpenClaw + ruby-ai + הגדרות
2. <code>build-radiant-image.sh</code> — build script (קורא גרסה + OpenClaw מה-manifest)
3. <code>radiant-config/</code> — נוצר אוטומטית ע"י ה-script (SOUL/IDENTITY/skills/memory)
<strong>הזרימה:</strong>
./build-radiant-image.sh v1.6.0
→ קורא manifest.json (גרסה + איזה OpenClaw)
→ מעתיק SOUL/IDENTITY/skills/memory ל-radiant-config/
→ בונה ruby-ai (standalone)
→ בונה turqiz/radiant:v1.6.0 (עם OpenClaw)
מצב ה-image וה-dev (בדיקה חיה)
| רכיב | מצב | הערה |
|---|---|---|
| `turqiz/ruby:v1.5.0` | קיים (972MB) | Next.js בלבד, בלי OpenClaw |
| `turqiz/ruby:v1.5.0-dev` | קיים (972MB) | אותו דבר |
| dev (3007) | רץ | `ruby-ai-dev` (עותק נפרד, לא tracked ב-git) |
| prod (3004) | רץ | `ruby-ai-prod` |
| health endpoint | ❌ היה 404 | ✅ תוקן (יצרתי route) |
ההפרדה dev → image → golden → live
<strong>העיקרון (כפי שהגדרת):</strong> כל שינוי נכנס ל-dev, לא ל-image/golden/live.
dev (3007, dev.ruby.turqizai.com) ← כל שינוי נכנס כאן קודם
↓ build + test
image (turqiz/radiant:vX.Y.Z) ← הקפאה (immutable)
↓ promote (admin)
golden master ← ברירת מחדל לטננט חדש
↓ rollout (canary → fleet)
live (3004, ruby.turqizai.com) ← משתנה רק ידנית
<strong>הפער:</strong> ה-pipeline של ה-image (rollout/golden/RBAC) קיים, אבל:
1. ה-image לא נבנה מ-dev אוטומטית (אין build script)
2. ה-image לא מכיל OpenClaw (עדיין "ruby" לא "radiant")
3. <code>ruby-ai-dev</code> הוא עותק נפרד, לא branch של git
שלוש הסביבות
| סביבה | URL | פורט | pm2 | tenant |
|---|---|---|---|---|
| Dev | `dev.ruby.turqizai.com` | 3007 | `ruby-ai-dev` | `tenant_dev_sandbox` |
| Prod (לייב) | `ruby.turqizai.com` | 3004 | `ruby-ai-prod` | כל הטננטים |
| Image/Golden | — | — | — | — |
ה-pipeline המלא (עם המספור שלנו)
1. עדכון OpenClaw מגיע (2026.8.1)
→ נכנס ל-DEV (dev.ruby.turqizai.com), לא נוגע בלייב
2. בודקים + מוסיפים שיפורים משלנו
3. מוציאים גרסה שלנו (v1.6.0) = ruby-ai + OpenClaw 2026.8.1 + skills + memory
4. בונים image (turqiz/radiant:v1.6.0)
5. מקדמים golden (admin בלבד)
6. מפיצים ללייב (canary → fleet, עם rollback)
הקשר manifest ↔ DB
manifest.json → "מה הגרסה הנוכחית שלנו" (קוד, מקור אמת)
TenantImage (DB) → "מה מקודם כ-golden" (מצב runtime)
Tenant.appVersion → "מה רץ אצל טננט X" (מצב runtime)
אחד מגדיר, השני משקף. לא מתנגשים.
החלטות
2026-10-01 13:03 CEST — [radiant]
- **החלטה:** Gap Analysis vs. Instinct: זוהו 10 פערים, 4 קריטיים (Audio/Browser/VirtualCard/Interceptor)
- **למה:** ניתוח ארכיטקטורת Instinct מול Ruby/Radiant — תוכנית 4 ספרינטים לסגירת פערים
2026-09-04 16:26 CEST — [radiant]
- **החלטה:** אינטגרציה לא נדרשת פעולה — WhatsApp כבר מחובר ומוכר
- **למה:** ה-webhook הודעת רישום אינטגרציה בלבד, לא דורש פעולת קוד
2026-09-04 14:43 CEST — [radiant]
- **החלטה:** אינטגרציה WhatsApp Business אושרה: tenant_25fa3e25c5bf1ac1 | whatsapp-business | 972545454034
- **למה:** Webhook hook מאישור אובייקטיבי - תואם את SKILL.md של whatsapp-web
2026-09-03 12:31 CEST — [radiant]
- **החלטה:** תשתית VPN עם טננט-איזולציה הושלמה — כל השכבות פועלות (Keycloak OIDC, Headscale ACLs, API-Bank SSO, Desktop Agent). נשאר רק להוסיף רשומת DNS A ל-vpn.turqizai.com כדי לאפשר TLS וגישה חיצונית.
- **למה:** המערכת מוכנה לייצור, ה-DNS הוא החסם היחיד
2026-09-03 12:11 CEST — [radiant]
- **החלטה:** דומיין vpn.turqizai.com ישמש כנקודת הגישה ל-Headscale VPN (במקום 127.0.0.1:8080). יש להוסיף רשומת A ב-DNS המצביעה ל-84.247.162.143
- **למה:** דומיין ייעודי מאפשר TLS, OIDC callback, והפרדה מ-API-Bank
2026-09-02 19:32 CEST — [radiant]
- **החלטה:** מחשב MSI לא מחובר ל־Radiant VPN — נדרש re-link ל־turqiz-main
- **למה:** ה־token שמור ב־vpn-state.json הוא tenantId=default וישן; wg show interfaces ריק; אין נתיב 10.127.0.0/24; TCP 5227 לא נגיש מרשת ה־Wi-Fi של המחשב (10035). רק לאחר SSO device-flow מחדש עם tenant=turqiz-main יתקבל token תקף והמנהרה תוקם.
2026-09-02 18:00 CEST — [radiant]
- **החלטה:** תיקון Radiant VPN — firewall UDP
- **למה:** ה-VPN לא התחבר כי ufw (Default deny incoming) חסם את פורטי UDP של WireGuard (5129/5227). ה-wireguard-manager יצר את ה-interfaces אבל מעולם לא פתח את הפורטים ב-firewall. תיקנתי: (1) הוספתי חוקי ufw ידניים לשני הפורטים הקיימים, (2) הוספתי פתיחת פורט אוטומטית ב-createInstance כדי שכל tenant חדש ייפתח אוטומטית. בנוסף: token ישן ב-MSI הוא tenantId=default במקום turqiz-main — צריך re-link.
2026-09-02 17:32 CEST — [radiant]
- **החלטה:** תיקון לולאת reset של WhatsApp gateway
- **למה:** ה-frontend שולח poll ל-/qr-code כל 3 שניות. ה-route הישן הפעיל initBaileys(null) בכל poll (כי התנאי (!sock && !connecting) || (pairingCode && !qrDataUrl) היה נכון), מה שאיפס את ה-socket וביטל את הקוד/QR שהמשתמש סרק. תיקנתי: poll רגיל לא מאפס, רק force=true. זה מסביר למה 'בטלפון מחובר אבל במערכת מנותק'.
2026-09-02 16:40 CEST — [radiant]
- **החלטה:** תיקון כפתורי WhatsApp ב-marketplace
- **למה:** הכפתורים 'סרוק QR קוד' ו'קבל קוד 8-ספרות' קראו ל-handleFetchQr ו-handlePairDevice שלא הוגדרו — ReferenceError שגרם לקריסת הדף. הוספתי את הפונקציות (fetch ל-/api/whatsapp/qr) + תצוגת pairingError.
2026-09-02 13:43 CEST — [radiant]
- **החלטה:** הסרת כורה קריפטו (XMRig) מהשרת
- **למה:** תהליך 'system-check' היה למעשה XMRig שכרה Monero ל-pool.supportxmr.com, צרך 293% CPU ו-2.1GB RAM, וחנק את השרת (load 7.8, RAM 164MB פנוי) — סיבה סבירה לכך שהמשק של רובי לא עבד. הותקן דרך SSH key של mozez@MSI מ-IP 85.250.90.112. הרגתי את התהליך ומחקתי את הקבצים. אין מנגנון persistence (cron/systemd/rc.local נקיים).
2026-09-02 12:07 CEST — [radiant]
- **החלטה:** תיקון דליפת מייל + גישור אינטגרציות ל-Radiant
- **למה:** שורש דליפת המייל: ruby/auth/login החזיר user.id=default קשיח, ו-google/callback שמר את הטוקן לפי state=default — כך הטוקן של mozez.a@gmail.com נשמר בדלי גלובלי משותף שכל מי שנופל ל-default רואה. שורש בעיית האינטגרציות: ה-UI כתב רק ל-integrations בלי לקרוא ל-connectIntegrationToRadiant, וה-sessionKey ruby-integration: נדחה עי allowedSessionKeyPrefixes. פתרון: רזולוציית user אמיתית + userId מ-id_token + bridge ייעודי + sessionKey תקין.
2026-09-02 09:56 CEST — [radiant]
- **החלטה:** שלב 7: איחוד federation — מחיקת federation-engine.ts לטובת federation-protocol.ts
- **למה:** שני מימושים כתבו לאותה collection (apibank_federation_connections) בסכמות שונות (engine: sourceRubyId/targetRubyId; protocol: id/sourceName/targetName) — התנגשות נתונים. ה-engine היה dead code (0 refs, discoverActions/executeRemoteAction היו mock-ים שלא קוראים ל-remote). ה-protocol הוא העשיר (tasks, chains, callbacks, webhooks, tenant-scoping) ומשמש את /api/gateway/federation/* + event-relay + trigger-engine + flow-engine. נשאר מימוש אחד.
2026-09-02 09:30 CEST — [radiant]
- **החלטה:** שלב 7: אכיפת tenant-scoping על /api/federation/* (engine) — tenantId מ-auth בלבד
- **למה:** ה-federation-engine.ts היה בלי שום auth: GET /api/federation/connections החזיר את כל החיבורים של כל הטננטים, ו-tenantId הגיע מ-query param (spoofable). זה הפר את עקרון ה-anti-spoofing (tenantId מ-auth, לא מהלקוח). עכשיו כל 6 ה-routes דורשים requireTenantAuth, וה-lookup מסונן לפי tenantId של ה-auth.
2026-09-02 07:36 CEST — [radiant]
- **החלטה:** agent-bridge: קריאת sessions.json index ישירה במקום 'openclaw sessions --json' (איטי ~30s)
- **למה:** ה-CLI sessions --json לוקח ~30s (סורק 41+ סשנים), אבל timeout היה 10s → pollForReply נכשל תמיד והחזיר '(לא התקבלה תשובה)'. קריאה ישירה ל-sessions.json (index ממופה לפי key) היא מיידית. CLI נשמר כ-fallback עם timeout 60s.
2026-09-02 06:34 CEST — [radiant]
- **החלטה:** הוספת logrotate ל-MongoDB (size 50M, copytruncate, rotate 7)
- **למה:** mongod.log תפח ל-248MB בלי שום רוטציה, מילא דיסק ל-87% והפיל את mongod ב-03:22. copytruncate נבחר כי mongod כותב ישירות ל-log בלי תמיכת rename בטוחה בלי SIGUSR1; postrotate שולח SIGUSR1 כגיבוי.
2026-09-01 19:23 CEST — [radiant]
- **החלטה:** ruby-ai-dev נשאר copy נפרד (לא git branch)
- **למה:** ה-copy הנוכחי (2.5GB) מבודד עם node_modules/.next/env משלו, לא git-tracked. git branch ידרוש משמעת merge/PR ויסבך את ההפרדה dev/live. copy נפרד פשוט יותר ומתאים לעקרון 'dev נפרד מ-live'. הוספתי ל-.gitignore.
2026-09-01 09:46 CEST — [radiant]
- **החלטה:** ארכיטקטורת חיבור ערוצים: הכל עובר דרך רובי (F-16I), לא ישירות ל-OpenClaw/Radiant
- **למה:** רובי הוא הממשק שמחליף את OpenClaw למשתמשי קצה ומוסיף הגדרות (personality, skills, whatsapp rules, זיכרון, כלים). ווצאפ קורא ל-/api/ruby/chat, רובי קורא ל-Radiant Gateway (openclaw/ruby_master).
2026-08-31 17:47 CEST — [radiant]
- **החלטה:** הגירה מלאה מ-OmniRoute ל-Ollama/Radiant
- **למה:** OmniRoute היה proxy חיצוני (20128) עם גישה ל-Claude/GPT/Gemini דרך ספקים חיצוניים. Ollama (11434) הוא ה-proxy המקומי של מנוע Radiant, OpenAI-compatible, כבר רץ. מיפוי: Claude->kimi-k2.7-code, GPT->glm-5.2, Gemini->gemma4, DeepSeek->deepseek-v4-pro/flash. OmniRoute נמחק לחלוטין.
2026-08-27 10:43 CEST — [radiant]
- **החלטה:** השקת מרכז האינטגרציות המלא (Integrations Hub & Directory) ב-ruby.turqizai.com/dashboard/integrations
- **למה:** בניית ממשק Hub מלא הכולל 760+ אפליקציות וכלים, סינון לפי 12 קטגוריות על, חיפוש חי, מגירת פירוט Triggers/Actions, כפתור Add to Workflow וכספת AES-256 Credential Vault
2026-08-27 10:30 CEST — [radiant]
- **החלטה:** איפיון מלא של קטלוג האינטגרציות וארכיטקטורת ה-Nodes על פי n8n (Integrations Hub Standard 4.0)
- **למה:** ניתוח מעמיק מתוך מאגר ה-GitHub של n8n (packages/nodes-base/nodes/), חלוקה ל-12 קטגוריות, תמיכה ב-Declarative Routing, Resource Locators, AI Agent Tools, ומנוע Ingestion לחילוץ 400+ Nodes ל-Ruby AI
2026-08-27 08:55 CEST — [radiant]
- **החלטה:** מנוע סכמות חכם אוניברסלי (Universal Schema Engine) לכל 727+ האינטגרציות וכלי ה-MCP (TradingView וכו')
- **למה:** חיבור resolveCompletePiece ו-resolveActionProps ישירות ל-StepSettingsPanel כך שכל כלי MCP (כולל TradingView) וכל 727 האינטגרציות מקבלים סרגל צד עשיר ומובנה עם כל השדות הטיפוסיים (Symbol, Timeframe, Exchange, Indicators, Data Fields) באופן אוטומטי, ללא סרגלים ריקים
2026-08-27 08:18 CEST — [radiant]
- **החלטה:** מימוש סטנדרט האינטגרציות המלא (Integration Sidebar Standard 3.0) ב-ruby-ai
- **למה:** הוספת מנגנון סינון שדות מותנה (showWhen / hideWhen בדומה ל-n8n displayOptions), הרחבת קטלוג האינטגרציות הסטנדרטיות (Telegram, Notion, Stripe, HubSpot, GitHub) עם Dynamic Resolvers, ותמיכה בטעינת תכונות דינמיות בזמן אמת
2026-08-27 08:14 CEST — [radiant]
- **החלטה:** אפיון n8n integration — 8 שכבות
- **למה:** התחרות ב-n8n דורשת drag&drop canvas + core nodes + AI cluster nodes. הבסיס שלנו חזק (727 pieces, API עשיר), החסם הקריטי היחיד הוא ה-canvas
2026-08-27 08:03 CEST — [radiant]
- **החלטה:** שדרוג מנוע האוטומציות ל-5 שלבי Enterprise (בהשראת n8n): מנוע DAG, Expression Engine, כספת מוצפנת, היסטוריית גרסאות, Pin Data, תור ביצועים ו-Replay
- **למה:** תמיכה מלאה בתחביר ביטויים n8n, הצפנת מפתחות AES-256-GCM, ניתוב תנאים רב-ענפי, תור מבוסס עדיפויות עם הגבלת Concurrency, שחזור גרסאות בלחיצה אחת, והרצה מחדש של ריצות כושלות
2026-08-27 08:03 CEST — [radiant]
- **החלטה:** הטמעת סרגל צד דינמי מלא בסגנון Activepieces + רכיבי קלט מתקדמים ו-Dynamic Props API
- **למה:** סרגל הצד שודרג לכלול MultiSelectChips, DynamicDropdown עם טעינה אסינכרונית וחיפוש, Array/Object repeaters, Expression toggle f(x), ו-Dynamic Sub-Forms עבור Airtable columns, Google Sheets headers ו-WhatsApp templates יחד עם מנהל חיבורי OAuth2
2026-08-26 10:54 CEST — [radiant]
- **החלטה:** ה-flow builder האמיתי הוא ruby-ai (list-based) — צריך להמיר ל-drag & drop ReactFlow
- **למה:** site היה מקום שגוי; ruby-ai הוא app הראשי עם 727 pieces ב-pieces-full.ts
2026-08-26 10:42 CEST — [radiant]
- **החלטה:** סגירת כל 3 הפריטים הפתוחים של flow builder
- **למה:** הרצה אמיתית דרך connection מוצפן, credentials hub, inputSchema מלא — כולם ממומשים
2026-08-26 10:15 CEST — [radiant]
- **החלטה:** שילוב flow builder: merge בין ADAPT source (188 קבצים) + Radiant templates (727 pieces)
- **למה:** שלא יהיה חסר כלום: להעתיק את כל רכיבי ה-builder של ActivePieces ולהוסיף node-source אחיד שמוזן מה-727 integration templates הקיימים ב-Mongo/API-Bank
2026-08-26 09:54 CEST — [radiant]
- **החלטה:** ספירת intents סופית = 39 (לא 46).
- **למה:** הספירה 46 כללה 7 intents שהוגדרו מראש בתכנון אבל לא מומשו ב-toolsMap. ה-39 הם מה שבאמת ממומש ונקשר ל-bridge.
2026-08-26 09:46 CEST — [radiant]
- **החלטה:** API Bank action execution מווגר כ-ops (לא code): key הזרקה דרך vault, הקוד 100% מוכן.
- **למה:** API key הוא secret של בעל tenant; נשאיר מחוץ לקוד.
2026-08-26 09:41 CEST — [radiant]
- **החלטה:** כל 8 שכבות האינטגרציה Ruby→Radiant הושלמו. הבא: אינטגרציה מלאה עם API Bank (payments/SMS/WhatsApp intents) כתוספות על הבסיס. federation = gateway-per-tenant (מודל א'), enrolled token חד-פעמי anti-spoofing.
2026-08-26 09:20 CEST — [radiant]
- **החלטה:** RCP intent router משתמש ב-Radiant native tools (לא OpenClaw HTTP endpoints). ה-bridge מחזיר RADIANT_EXECUTE הוראה שהסוכן מבצע
- **למה:** ב-Radiant הכלים הם יכולות ה-agent עצמו, לא שרת חיצוני. dependency-injection dispatcher שומר על בדיקות נקיות
2026-08-26 07:53 CEST — [radiant]
- **החלטה:** Automation Hub: לבנות מרכז אוטומציה מלא ברמה של Activepieces בתוך ruby-ai
- **למה:** המשתמש דורש לייצא את כל יכולות Activepieces — flow builder, connections, אינטגרציות, הרצות — לתוך הדשבורד של רובי. הדף הקיים הוא רשימת Workflows בסיסית בלבד. לבנות UI עשיר + להשתמש ב-existing api/ruby/automation backend.
2026-08-25 13:22 CEST — [radiant]
- **החלטה:** MongoDB auth enabled with SCRAM-SHA-256. Admin user: admin/TurqizAdmin2026!. App user: turqizai_app/TurqizApp2026!. Connection string: mongodb://turqizai_app:...@127.0.0.1:27017/turqizai?authSource=turqizai
- **למה:** בינארי נקי v8.0.31 מ-apt, SCRAM עובד תקין
2026-08-25 12:50 CEST — [radiant]
- **החלטה:** WhatsApp → Radiant סינכרוני דרך `/v1/responses` (OpenAI-compatible). החלפנו את `/hooks/agent` (async, לא החזיר תגובה ל-WhatsApp) ב-`/v1/responses` (sync, תגובה מיד באותה קריאה). הפעלנו `gateway.http.endpoints.responses.enabled` ב-Radiant.
- **מה ששונה:** whatsapp-gateway `server.js` — שורות 523-570 עברו מ-`POST /hooks/agent` ל-`POST /v1/responses` עם `model:"openclaw"` + `x-openclaw-session-key`. תגובה נשלפת מ-`d.output[].content[].text` ונשלחת ל-WhatsApp דרך Baileys.
- **אימות live:** `"תגיד: שלום רובי"` → `"שלום רובי! 👋"` ✅ | whatsapp-gateway connected ✅ | אין hooks/agent בקוד ✅ | אין 3004 בקוד ✅
- **גיבויים:** `server.js.bak.ruby-ai` (מקורי), `server.js.bak.hooks-agent` (גרסת async)
- **Auto-provisioning:** עדיין פעיל (שורות 275-297) — כל חיבור WhatsApp חדש נרשם אוטומטית ל-api-bank federation bridge
- **דף דאשבורד:** `src/app/dashboard/whatsapp/page.tsx` — UI מלא (QR, pairing, סטטוס Radiant, קבוצות, שליחת הודעה). tsc נקי, build כללי נפל (MODULE_NOT_FOUND לא קשור לדף).
- **מצב ערוצים:** WhatsApp ✅ | Telegram ✅ | API 5501 ✅ | MCP 24.5K ✅ | דפדפן ✅ | טלפון ✅ | מחשב ✅ — 9 פלאגינים פעילים ב-Radiant
2026-08-23 22:43 CEST — [radiant]
- **החלטה:** Code Mode אמיתי (Cloudflare search-and-execute) מומש ונבדק live. חדש: `src/lib/api-bank/code-mode.ts` (node:vm sandbox מבודד + timeout) + `src/app/api/codemode/route.ts` (POST /api/codemode). ה-`execute_code` ב-MCP server נכתב מחדש: במקום dispatch של actions, עכשיו מריץ JavaScript שהמודל כותב מול אובייקט `ruby` (search/execute/get/list) ב-sandbox. tenantId מוזרק מהשרת (anti-spoofing, לא מהקוד).
- **אימות live:** `40+2` → 42 ✅; `ruby.list()` → templates אמיתיים מ-Mongo ⭢; אבטחה: process/require/fetch = undefined ✅; לולאה אין-סופית → timeout 5s ✅.
- **למה:** השלמת הפער בין התיעוד (ruby-code-mode-spec.md/code-mode.md) למימוש — ה-`execute_code` הקודם היה dispatch, לא JS sandbox. עכשיו = 2 tools כמו Cloudflare: search + execute(JS).
2026-08-23 20:42 CEST — [radiant]
- **החלטה:** admin subdomain נעול: admin.ruby.turqizai.com = מערכת ניהול מקיפה על api-bank + radiant. SSO Keycloak PKCE עובד, requireAdmin מעביר JWT עם admin role.
2026-08-23 18:27 CEST — [radiant]
- **החלטה:** המרת ruby.turqizai.com לעבוד עם api-bank+radiant (אופציה B): api-bank=ה-API היחיד (control plane לכל tenant), radiant=orchestrator. מערכת הניהול על /admin בינתיים; צריך subdomain ייעודי admin.ruby.turqizai.com בעתיד (דורש IONOS API key חדש).
2026-08-23 16:25 CEST — [radiant]
- **החלטה:** שלב 7 + 8 הושלמו בקוד. שלב 7 (Federation on top of Nodes): tenant-scoping מלא — ConnectionRegistry קיבל tenantId מנדטורי + index, federation.ts נכתב מחדש (כל הפונקציות tenant-scoped + validateApiKeyGlobal), auth.ts מחלץ tenantId מ-x-tenant-id header (anti-spoofing: לא מה-Body), routes federation/connectionId מעדכנים tenantId. שלב 8 (Events → Cron/webhooks): tenantId מנדטורי ב-event subscription (events.ts) + מודול event-scheduler.ts חדש (webhook delivery עם retry+backoff+tracing, processDueDeliveries cron tick, getDeliveryStats) + endpoint /api/rcp/events/deliver. typecheck נקי — כל השגיאות הנותרות pre-existing בקבצים אחרים.
- **למה:** מיזוג Federation/Events מעל Nodes עם multi-tenant isolation (tenantId בכל רשומה + filtered lookup).
2026-08-23 15:24 CEST — [radiant]
- **החלטה:** MongoDB auth שוחזר במלואו. הסיבה האמיתית ל-'storedKey mismatch': לא נוזקה ולא binary מזויף — אלא שתי סיסמאות מתנגשות (AdhnXaiYRwPvRh22MUiC בחלק מה-apps, eNg5C7Pj8e13858evk6vcoTN באחרות) + תצוגת mongosh מטעה (getUser() החזיר credentials ריק אבל ב-disk ה-SCRAM-SHA-256 היה תקין). פתרון: סיסמה חדשה אחידה (24-char) לכל ה-8 apps + authorization:enabled + drop admin/nodetest/testuser/recreate turqizapp עם role root לניקוי. אימות: NO-AUTH READ FAILED (13 Unauthorized) + AUTH WRITE+READ OK + 14 חיבורי אפליקציות פעילים.
- **למה:** re-enable auth בלי לשבור אפליקציות: איחוד סיסמאות + בדיקת auth חיה.
2026-08-23 15:08 CEST — [radiant]
- **החלטה:** תיקון ממצא קודם: ה-Firewall למעשה קיים ועובד — ufw Active עם Default deny (incoming), allow (outgoing), deny (routed). הטעות הקודמת הייתה ש-ufw לא היה ב-PATH (נמצא ב-/usr/sbin/ufw). השירותים החשופים בכוונה: SSH 2222, Web 80/443, Mail 25/465/587/993/143, omniroute 20128/20129/20132. Gateway 18789 חסום ע"י deny-default (לא מפורש).
- **למה:** דיוק הממצא: אין צורך להתקין Firewall חדש — הוא כבר פעיל. מה שנותר: MongoDB authorization:disabled → re-enable, ו-18789 לוודא שלא צריך חשיפה.
2026-08-23 15:06 CEST — [radiant]
- **החלטה:** וקטור ההדבקה החוזרת זוהה: אין Firewall כלל (ufw inactive + iptables ריק ללא אפילו default policy). sshd מאובטח (Port 2222 + PermitRootLogin prohibit-password + PasswordAuthentication no) — כל brute-force נחסם, logins לגיטימיים רק מ-IP של Mozez (85.250.17.28 / 79.181.172.131). שירותים חשופים ל-0.0.0.0 ללא הגנה: omniroute (20128/20129/20132), headscale (*:8101), mail 25/465/587/993/143, nginx 80/443, node 3000-3006. MongoDB authorization:disabled (bindIp 127.0.0.1 בלבד).
- **למה:** חייב Firewall כשכבה ראשונה — אחרת כל שירות חשוף לאינטרנט וזה הסיבה ל-6 הידבקויות חוזרות.
2026-08-23 15:06 CEST — [radiant]
- **החלטה:** בדיקת אבטחה מעמיקה: אין נוזקה פעילה כרגע (אין חיבור ל-C2 193.32.162.73, אין xmrig, authorized_keys נקי, mongod גרסה 8.0.21 רשמית מ-apt). וקטור ההדבקה החוזרת מזוהה: אין Firewall כלל (ufw inactive + iptables ריק) עם שירותים חשופים ל-0.0.0.0 (omniroute 20128-20132, headscale 8101, mail, nginx). MongoDB רץ authorization:disabled (bindIp 127.0.0.1). mtime של mongod = Dec 2013 (מזויף, לא נוזקה — dpkg -V תקין חוץ מ-mongod.conf).
- **למה:** לזהות למה נדבק 6 פעמים: היעדר Firewall = שירותים חשופים ישירות לאינטרנט. SSH עצמו מאובטח (Port 2222 + no password + no root password).
2026-08-23 11:28 CEST — [radiant]
- **החלטה:** MongoDB אומת להפעלה ללא auth (authorization: disabled) כי SCRAM-SHA-256 נשבר — storedKey נכון ב-DB אך mongod מחשב אחרת (storedKey mismatch) אפילו על user טרי עם סיסמה פשוטה. חשד ל-binary tampering ע"י נוזקה (mtime מזויף 2013). הפתרון הזמני: no-auth localhost-only + ecosystem.config.js עבור env injection.
- **למה:** SCRAM broken at binary level; no-auth on 127.0.0.1 is secure enough short-term; must reinstall mongod from clean source before re-enabling auth.
2026-08-23 10:25 CEST — [radiant]
- **החלטה:** Stage 6 agent-bridge: החלפת CLI subprocess ב-Gateway HTTP hooks (POST /hooks/agent). pollForReply מחכה לתשובת assistant ב-session transcript. browser-automation תוקן לטיפול exit codes.
- **למה:** CLI subprocess היה איטי ו-unreliable (timeout 120s). Gateway hooks = async, מחזיר runId מיד, poll session file לתשובה. תיקון browser CLI: stdout JSON עם ok=true נחשב success גם כש exit code nonzero (stderr warnings).
2026-08-23 10:08 CEST — [radiant]
- **החלטה:** Ruby Auth Stack הושלם: Keycloak (realm ruby + client ruby-client) על 8081, Permify (tenant ruby + schema user/tenant/robot/dashboard) על 3476/3478, Postgres שני DBs (keycloak+permify), DNS id.turqizai.com → 84.247.162.143, TLS Let's Encrypt, nginx vhost. JWT RS256 מאומת מול JWKS עם jose.
- **למה:** הקמת מערכת אימות+הרשאות מלאה (SSO + Zanzibar authorization) לרוביז של Turqiz. נפתרו: IONOS DNS דורש מערך [{}], פורט 8080 תפוס ע"י headscale → 8081, Permify crash-loop כי user permify לא היה קיים ב-Postgres.
2026-08-22 19:42 CEST — [radiant]
- **החלטה:** תועדו דרישות חוקיות ל-Headscale: רישיון BSD 3-Clause מותר שימוש מסחרי. חובה: TLS, פרטיות, תנאי שימוש, הגנת נתונים. מסמך מלא: /root/.openclaw-shared/docs/headscale-legal-compliance.md
- **למה:** תיעוד דרישות משפטיות ו-compliance לפני המשך מימוש
2026-08-22 18:50 CEST — [radiant]
- **החלטה:** תוכנית ארכיטקטונית ל-Headscale Per-Instance + Tenant Management נכתבה ל-/root/.openclaw-shared/docs/headscale-tenant-design.md. מחכה לאישור לפני מימוש.
- **למה:** תיעוד מלא לפני תחילת מימוש — כולל ארכיטקטורה, מודלי נתונים, API, אבטחה, ותוכנית עבודה ל-5 שבועות
2026-08-22 16:34 CEST — [radiant]
- **החלטה:** Stage 6 — reuse existing Ruby Chrome Extension (turqiz-ai/ruby-chrome-extension v4.0.1) and redirect server-side logic to Radiant via TOSP-compatible adapter.
- **למה:** Extension is a thin client (TOSP); replacing server is cheaper than rebuilding extension. Adds 2 RCP intents (execute_browser_automation, query_page_context) and 6 REST routes under /api/ruby/*.
2026-08-22 13:18 CEST — [radiant]
- **החלטה:** Public MCP registry = consume דרך mirror Hybrid (metadata mirror + on-demand full import). לא scrape HTML (SPA), אלא API נקי /v0.1/servers. שום דבר לא live אוטומטית — הכל queued.
- **למה:** החיפוש רואה אלפים מיד בלי למשוך GBs מיותרים. controlled כמו Intent Discovery.
2026-08-22 12:37 CEST — [radiant]
- **החלטה:** Registry = פנימי self-hosted (לא הציבורי). נבנה על IntegrationTemplate הקיים + apibank_registry_entries. Controlled publish כמו Intent Discovery. namespace io.<tenant>/<name>; review דורש operator auth (APIBANK_API_KEY).
- **למה:** שליטה מלאה + multi-tenant isolation + לא חושף IP/creds פנימיים. הציבורי נשאר אופציה עתידית לצריכה/פרסום.
2026-08-22 12:08 CEST — [radiant]
- **החלטה:** MCP = Option 2: שרת MCP מוטמע בתוך api-bank (STDIO ישיר ל-SDK, לא HTTP-עוקף). רשום ב-OpenClaw/Radiant תחת mcp.servers.radiant-apibank. 9 כלים: search_tools, execute_code, list_available_actions, gateway_status, list_templates, get_template, test_integration, manage_vault, federation_connections.
- **למה:** Rejected Option 1 (wrapper נפרד על REST) — Option 2 מדבר ישירות עם actionRouter/SDK, ללא קפיצת HTTP נוספת, ואנטי-ספופינג tenantId מ-auth.
2026-08-22 11:06 CEST — [radiant]
- **החלטה:** doc.turqizai.com הוקם (DNS+nginx+TLS)
- **למה:** subdomain חדש שמגיש את אתר התיעוד מ-docs/ בצורה ציבורית, אבטח HTTPS, מתעדכן אוטומטית
2026-08-22 11:06 CEST — [radiant]
- **החלטה:** 3 רמות בידוד (isolation levels)
- **למה:** כל tenant נבנה מאותו template עם `--isolation-level` (1|2|3). רמה 1 = process+schema (אותו Postgres, דמו/free); רמה 2 = process+DB instance נפרד (משלמים); רמה 3 = VM+DB+KMS (Pay/PCI). קוד+נתונים קבועים; רק "איפה רצים"+"איפה מפתחות" משתנים. מעבר = `migrate-tenant-level.sh` בלי לשנות קוד
2026-08-22 11:05 CEST — [radiant]
- **החלטה:** Ruby Code Mode Engine (MCP 2-Tools Pattern)
- **למה:** אימוץ ארכיטקטורת Search-and-Execute (Cloudflare Code Mode) עבור API-Bank ו-RCP לחיסכון של 90% בטוקנים, שרשור פעולות במילישניות ובידוד טננטים ב-Sandbox
2026-08-22 10:45 CEST — [radiant]
- **החלטה:** logs.sh תוקן
- **למה:** bug ב-[ -n ] בסוף log
2026-08-22 10:43 CEST — [radiant]
- **החלטה:** מערכת תיעוד חי (logs.sh) היא מקור האמת
- **למה:** append-only + CLI + status.json
2026-08-25 09:08 CEST — [radiant]
- **החלטה:** קטלוג אינטגרציות מאוחד — קובץ אחד. 3 קבצים מפוזרים מוזגו לקובץ יחיד `integration-templates.ts`: 416 פנימיים + 724 Activepieces (712 חדשים + 12 dedupe) = 5501 אינטגרציות ייחודיות. `pieces-catalog.ts` ו-`unified-catalog.ts` נמחקו. `flow-engine.ts` עבר להשתמש רק ב-`integrationTemplates` (הוסר `slice(0,200)` + הוסר import של piecesCatalog). כפילות אמיתית `week-done` (שכפול `weekdone`) נמחקה.
- **בדיקת חיבורים:** כל הרכיבים מחוברים — code-mode→sdk→engine→rcp-translator, mcp/server→apiBankEngine+actionRouter+registryEngine+runCodeMode, flow-engine→federation-protocol→action-router, אוטומציות→federation-protocol. 0 כפילויות id. 81 "שמות כפולים" = auth גנרי חוקי.
- **אימות live:** typecheck נקי ✅ | build נקי ✅ | pm2 online ✅ | codemode `1+1`→success ✅ | mcp/convert HTTP 200 ✅ | catalog/integrations/marketplace 401 (auth תקין) ✅
- **למה:** מזעור מקורות אמת — קובץ קטלוג אחד שכל הרכיבים (code-mode, flow-engine, mcp, sdk) קוראים ממנו.
- **תיעוד:** `unified-catalog.md` (חדש), `code-mode.md` + `mcp-map.md` (עודכנו).
2026-08-27 18:28 CEST — [radiant]
- **החלטה:** אפיון מלא לממשק ניהול טננטים — Admin Control Center
- **למה:** הממשק הקיים (page.tsx) בסיסי מדי. נכתב מסמך איפיון מלא ל-AI Code Builder המכסה:
1. <strong>Overview</strong> — KPI cards (MRR, tenants, MAU, errors), charts, live activity feed, system health bar
2. <strong>Tenants</strong> — טבלה + Drawer ב-640px עם 8 tabs (overview, users, billing, tokens, agents, integrations, audit, settings)
3. <strong>Users</strong> — ניהול משתמשים cross-tenant, sessions management, force logout, impersonation
4. <strong>Billing</strong> — subscriptions, invoices, plan changes, dunning, MRR/ARR stats
5. <strong>Token Usage</strong> — per-tenant breakdown, model attribution, quota management, threshold alerts
6. <strong>Plans</strong> — CRUD plans עם feature matrix, model allowlist, isolation level
7. <strong>Agents</strong> — cross-tenant agent monitoring, performance, conversations
8. <strong>System Health</strong> — service pings (Radiant/Keycloak/MongoDB/Redis/WhatsApp/Permify)
9. <strong>Logs</strong> — searchable log viewer + live SSE tail
10. <strong>Queues</strong> — queue stats, failed jobs, retry/flush
11. <strong>Audit Log</strong> — immutable event log לכל פעולות האדמינים
12. <strong>Settings</strong> — email templates, webhooks, security, billing config, notifications
- **API חסרות שיש לבנות:** /users, /billing, /tokens, /system, /audit, /settings (תחת /api/admin/control/)
- **Data Models:** Subscription, Invoice, TokenUsageRecord, TenantTokenQuota, PlatformUser, UserSession, AuditEvent, ServiceHealth, QueueStats
- **Stack:** Next.js 14 App Router, TypeScript, Tailwind+Radix UI, Recharts, SSE for live logs
- **Security:** JWT RS256, role=admin, anti-spoofing (tenantId from JWT), impersonation with audit
- **Artifact:** admin_control_center_spec.md בזיכרון המשותף
2026-08-27 19:22 CEST — [radiant]
- **החלטה:** השלמת פיתוח ופריסת ממשק הניהול המלא (Admin Control Center Suite) ב-api-bank
- **למה:** הממשק נבנה מחדש בהתאמה מלאה לשפת העיצוב Light של Ruby AI (רקע #F8F9FB, כרטיסים לבנים עם גבול #E5E7EB, כפתורי #1A73E8, תגיות סטטוס מותאמות).
- **רכיבים שנפרסו:**
1. עמודי ניהול: Overview, Tenants (עם Drawer מלא), Users, Billing (מנויים וחשבוניות), Token Usage (מכסות ופילוח מודלים), Plans, Agents, System Health (פינגים לשירותים), Logs, Queues, Audit Log, Settings.
2. 12 נקודות קצה (API routes) מאובטחות עם Keycloak JWT RS256 תחת <code>/api/admin/control/*</code>.
- **סטטוס:** נבנה ונפרס בהצלחה, HTTP 200 מאומת ב-admin.ruby.turqizai.com.
2026-08-27 20:22 CEST — [radiant]
- **החלטה:** הטמעת מודול Multi-Tenant Core Operations המלא ב-api-bank
- **למה:** השלמת הפינות הקריטיות בניהול טננטים:
1. <strong>אשף הקמת טננט חדש (Onboarding Wizard 4 שלבים):</strong>
- Step 1: פרטי חברה ומנהל (name, email, type).
- Step 2: בחירת תוכנית + בחירה ויזואלית של **3 רמות בידוד** (Level 1 Shared DB, Level 2 Dedicated DB, Level 3 Dedicated Container/VM + KMS).
- Step 3: הגדרת מודלים מורשים (GPT, Claude, Gemini), הגבלת סוכנים ו-Webhook URL.
- Step 4: חשיפה חד-פעמית ומאובטחת של ה-API Key (`rby_...`) עם כפתור העתקה בלחיצה אחת.
2. <strong>מגירת טננט ברוחב 680px עם 8 טאבים פעילים:</strong>
- Overview (כולל ארכיטקטורת רמת בידוד ו-KPIs)
- Users (רשימת משתמשים פר טננט)
- Billing (מצב מנוי, מחזור חיוב וחשבוניות)
- Tokens (מעקב צריכה פר מודל ומכסות)
- Agents (סוכנים פעילים ושיחות)
- Integrations (סטטוס חיבורים ואינטגרציות)
- Audit Log (ציר זמן פעולות מנהל)
- Settings (שינוי תוכנית, סטטוס, הגדרות, ו-**מיגרציית רמות בידוד 1-2-3**).
3. <strong>סבב מפתחות API (Key Rotation Modal):</strong> מודאל אישור והצגת מפתח חדש עם אפשרות העתקה מיידית.
- **סטטוס:** נבנה, נפרס ונבדק בהצלחה ב-admin.ruby.turqizai.com/tenants.
2026-08-27 20:36 CEST — [radiant]
- **החלטה:** פריסת Impersonation, Command Palette (Cmd+K) ו-Notification Center + אימות ארכיטקטורת RBAC מלאה
- **רכיבים שנפרסו:**
1. <strong>Impersonation (התחברות בשם טננט):</strong>
- Endpoint: `POST /api/admin/control/tenants/[tenantId]/impersonate` מאומת עם Keycloak JWT ורושם ב-`apibank_api_logs`.
- כפתור `🔑 Login as Tenant` בטבלת הטננטים ובמגירת הטננט פותח ישירות סשן מבודד ב-Ruby AI.
2. <strong>Global Command Palette (חיפוש מהיר <code>Cmd+K</code> / <code>Ctrl+K</code>):</strong>
- Endpoint: `GET /api/admin/control/search?q=<query>` מבצע חיפוש חוצה טננטים, משתמשים, סוכנים ועמודי מערכת.
- מודאל Spotlight עם ניווט מקלדת מלא (חצים / Enter / Escape).
3. <strong>Notification Center (פעמון התראות עליון):</strong>
- Endpoint: `GET /api/admin/control/notifications` מתריע על חריגות מכסת טוקנים (>85%), שגיאות שרת ותקלות בתורים.
- Dropdown אינטראקטיבי עם תג מונה התראות אדום וקישורים לפעולה מהירה.
4. <strong>אימות RBAC מלא (3 שכבות אבטחה):</strong>
- שכבה 1 (Platform): Keycloak Realm `ruby` עם תפקידי `super_admin`, `admin`, `system_admin`.
- שכבה 2 (Tenant Authorization): Keycloak RS256 JWKS + `admin-auth.ts` / `ruby-auth.ts` עם בדיקת Bearer Token.
- שכבה 3 (Fine-Grained AuthZ & Isolation): מנוע Permify (Google Zanzibar) על פורט 3476 ובידוד `tenantId` למניעת Spoofing.
- **סטטוס:** הכל נבנה, נבדק, קומפל בהצלחה (Next.js 14.2.5) ורץ חי ב-admin.ruby.turqizai.com.
2026-08-27 20:41 CEST — [radiant]
- **החלטה:** הקמת 3 משתמשי בדיקה וטננטים ל-3 רמות הבידוד של ה-Multi-Tenant
- **פרטי חשבונות הבדיקה:**
1. <strong>Level 1 (Shared Schema):</strong>
- Tenant: `Alpha Retail Ltd` (`tenant_lvl1_shared_01`), Plan: `starter`, Isolation: Level 1
- User: `lvl1-admin@turqizai.com` | Password: `Turqiz2026!`
- API Key: `rby_lvl10001_...`
2. <strong>Level 2 (Dedicated Database):</strong>
- Tenant: `Beta FinTech Corp` (`tenant_lvl2_dedicated_02`), Plan: `business`, Isolation: Level 2
- User: `lvl2-admin@turqizai.com` | Password: `Turqiz2026!`
- API Key: `rby_lvl20002_...`
3. <strong>Level 3 (Dedicated Container + KMS):</strong>
- Tenant: `Gamma Health Global` (`tenant_lvl3_enterprise_03`), Plan: `enterprise`, Isolation: Level 3
- User: `lvl3-admin@turqizai.com` | Password: `Turqiz2026!`
- API Key: `rby_lvl30003_...`
- **אימות:** בדיקת אימות ישירה מול Keycloak OIDC Token endpoint עברה בהצלחה (200 OK) עבור כל 3 המשתמשים.
2026-08-27 20:56 CEST — [radiant]
- **החלטה:** בידוד מוחלט של Header ו-Layout ה-Admin + מנגנון `adminAuthClient` לרענון טוקנים שקוף
- **תיקונים שבוצעו ונפרסו:**
1. <strong>בידוד ה-Root Layout:</strong> נוצר <code>GlobalNavWrapper.tsx</code> המסתיר לחלוטין את ה-AuthBar, ה-Navbar וה-Footer של API Bank בכל ניווט תחת <code>/admin/*</code>. כעת מוצג רק ה-Header הנקי של Ruby Admin.
2. <strong>מנגנון <code>adminAuthClient</code>:</strong> כל עמודי ה-Admin (<code>tenants</code>, <code>overview</code>, <code>integrations</code>, <code>plans</code>, <code>layout</code>) משתמשים כעת ב-<code>adminFetch</code>. במקרה של טוקן פג תוקף מתבצע רענון OIDC אוטומטי (<code>/api/admin/oidc</code>), ובמקרה של חוסר אימות מבוצעת הפניה חלקה ל-Keycloak במקום הצגת טבלה ריקה.
- **סטטוס:** ה-Build הושלם בהצלחה, `pm2 restart api-bank` בוצע ונבדק.
צ׳קליסט מערכת
🔍 צ'קליסט מערכת — בדיקה מלאה (2026-08-25)
עדכון 19:28 — n8n הוסר מהמערכת, 12 שירותי PM2 online ✅
🟢 שירותי PM2 (12/12 online)
| שירות | פורט | מצב |
|---|---|---|
| api-bank | 3006 | 🟢 online |
| api-bank-worker | — | 🟢 online ✅ |
| ruby-ai | 3004 | 🟢 online |
| radiant-gateway | 18790 | 🟢 online |
| whatsapp-gateway | 3090 | 🟢 online |
| crm | 3005 | 🟢 online ✅ |
| turqiz-pay | 3002 | 🟢 online ✅ |
| turqiz-site (כולל mail) | 3001 | 🟢 online ✅ |
| chatbuilder | — | 🟢 online ✅ |
| ruby-mcp-server | 18795 | 🟢 online ✅ |
| rcp-api | — | 🟢 online ✅ |
| headscale-demo | — | 🟢 online ✅ |
🟢 Docker Containers (5/5)
| קונטיינר | פורט | מצב |
|---|---|---|
| omniroute | 20128 | 🟢 Up (LLM proxy) |
| omniroute-redis | 6379 | 🟢 Up |
| ruby-auth-keycloak | 8081 | 🟢 Up (SSO) |
| ruby-auth-permify | 3476 | 🟢 Up (AuthZ) |
| ruby-auth-postgres | 5432 | 🟢 Up |
✅ תקלות שנפתרו היום
| תקלה | סיבה | תיקון |
|---|---|---|
| crm 502 | MongoDB סיסמה ישנה | עדכון env + restart |
| pay 502 | MongoDB סיסמה ישנה | עדכון env + restart |
| turqiz-site 502 | חסר BUILD_ID + orphan proc + סיסמה | build + kill orphan + restart |
| ruby-ai /api/ruby/ | nginx הפנה ל-3006 | תוקן ל-3004 |
| Telegram bot | DeepSeek credentials | המשתמש הוסיף token |
| 6 שירותי PM2 מושבתים | מעולם לא הודלקו / סיסמה ישנה | start + env fix |
🟢 תקין
- כל דפי הדאשבורד (24 עמודים)
- כל הדומיינים (crm, pay, n8n, mail, rcp) → 200
- SSO: Keycloak + Permify + Better Auth
- Telegram bot (@ruby_ai_972545454034_02702_bot)
- WhatsApp (baileys-v7)
- DeepSeek LLM (OmniRoute)
- MongoDB (v8.0.31, auth enabled)
- Nginx
היסטוריית שינויים
2026-10-04 09:44 CEST — [radiant]
- הסרת ספקים עודפים (9router, deepseek, google, google-vertex, kimi-code, ninerouter, nvidia, ollama-local, omniroute, openrouter, xai, ollama-cloud), איפוס נעילות סשנים (כולל סשן f2576e1b), ואימות מענה של ollama/deepseek-v4.1-flash
- שלב: Providers Cleanup
2026-10-04 09:24 CEST — [radiant]
- תיקון Ollama ב-chat.turqizai.com: עדכון API key תקף, הסרת מודלים בדימוס (glm-5.1, qwen3.5:397b, deepseek-v4-flash:0731), איפוס auth cooldown וסנכרון systemd override ו-openclaw.json
- שלב: Ollama Fix
2026-10-02 16:00 CEST — [radiant]
- Ruby-Desktop-Setup-3.5.9.exe נבנה ופורסם (103MB) — כולל: SSO Device Flow, VPN WireGuard, Workspace Daemon, Browser Bridge, electron-builder NSIS
- שלב: Unified Installer
2026-10-02 15:49 CEST — [radiant]
- Install-Ruby-Desktop.ps1 הועלה — installer מאוחד (SSO+Node+VPN+App+Registry+Report) גרסה 1.0.0
- שלב: Unified Installer
2026-10-02 15:43 CEST — [radiant]
- נוספו API routes חדשים: /api/desktop/install-report + /api/nodes/register — תומכים ב-Installer המאוחד
- שלב: Unified Installer
2026-10-01 13:12 CEST — [radiant]
- הועלה Gap Spec vs. Instinct לאתר doc.turqizai.com — סקשן חדש: Gap Spec (10 פערים, 4 ספרינטים)
- שלב: Gap Spec Published
2026-09-05 18:35 CEST — [radiant]
- Orchestration (חלק ב') הושלם: docker-compose template + generate-compose.ts נבנו. generate-compose סרק 6 tenants ויצר docker-compose-tenants.yml עם service לכל tenant (port mapping, volumes, healthcheck). gateway-health-check.ts מאשר ש-6 gateways מוגדרים (לא רצים עדיין — דורש docker compose up).
- שלב: orchestration
2026-09-05 18:27 CEST — [radiant]
- Orchestration (חלק א'): batch-provision.ts נבנה ונבדק. יצר 5 tenants (demo-001..005) עם ports ייחודיים, configs, enrollment tokens (7 ימים). כל tenant = workspace/state/config נפרדים תחת /root/tenants/. מוכן להרחבה ל-500.
- שלב: orchestration
2026-09-05 17:55 CEST — [radiant]
- שלב 8 הושלם: Events Pub/Sub + Webhook delivery נבנה ונבדק E2E. subscribe/emitEvent/unsubscribe/listSubscriptions עובדים מול PostgreSQL. בדיקות: matching event delivered ✅, non-matching filtered ✅, unsubscribe stops delivery ✅, event_log audit trail ✅. טבלאות event_subscriptions + event_log קיימות עם RLS.
- שלב: 8
2026-09-05 17:44 CEST — [radiant]
- שלב 7 (חלק ג') הושלם: cross-tenant isolation verification עבר 5/5 בדיקות. node של tenant-3 לא נגיש מ-tenant-1, enrollment token used/invalid נדחים, tenant לא קיים נדחה ב-RCP route, node sets disjoint בין טננטים. שלב 7 Federation on top of Nodes הושלם במלואו.
- שלב: 7
2026-09-05 17:42 CEST — [radiant]
- שלב 7 (חלק ב') הושלם: enroll-node flow נבנה ונבדק. מאמת enrollment token (חד-פעמי, expiry), מפיק tenantId, מעדכן tenant_nodes ל-status=paired עם nodeId אמיתי, מסמן token כ-used. E2E: test-tenant-3 + msi-desktop-001 → paired בהצלחה, gatewayToken הוחזר.
- שלב: 7
2026-09-05 17:37 CEST — [radiant]
- שלב 7 (חלק א') הושלם: provision-tenant CLI נבנה ונבדק. יוצר tenant ב-DB + workspace/state/config dirs + openclaw.json עם port ייחודי (19000+offset) + enrollment token חד-פעמי. test-tenant-3 נוצר בהצלחה (port 19126, token enr_W17...). טבלת tenant_nodes קיימת עם RLS-ready schema.
- שלב: 7
2026-09-05 17:27 CEST — [radiant]
- שלב 6.8 הושלם: LLM bridge כולל instructions שמנחים שימוש ב-web_search/web_fetch. E2E: query 'מה מזג האוויר בתל אביב עכשיו?' החזיר תשובה עם טמפרטורה (30-32°C), לחות, רוח — ה-LLM השתמש בכלים פנימיים של OpenClaw.
- שלב: 6.8
2026-09-05 17:11 CEST — [radiant]
- שלב 6.7 הושלם: RCP Router wired ל-OpenClaw LLM via /v1/responses + bearer auth + model=openclaw. intent query מחזיר תשובה אמיתית (לא pending). E2E מלא: X-Tenant-ID → resolveAuth → route() → callLLM → gateway → response.
- שלב: 6.7
2026-09-05 16:52 CEST — [radiant]
- שלב 6.6 הושלם: RCP API E2E עובד. תיקון dev-fallback ב-resolveAuth (X-Tenant-ID כש-OIDC מושבת). tenant test-tenant-1 פעיל, /route מחזיר envelope תקין עם executedBy=agent-reasoning(LLM). intent chat מסומן external — צריך wiring ל-LLM בשלב הבא.
- שלב: 6.6
2026-09-04 22:26 CEST — [radiant]
- שלב 6.6 הושלם בהצלחה: E2E מלא דרך api-bank port 3006 עם rxt_ token. provision → authenticateExtension → tospTaskToRcp(chat) → queryAgent → Radiant LLM → reply חזר תוך ~12s. התשובה: 'השעה כרגע היא 22:25 (10:25 PM) בשעון ברלין, יום שישי, 4 בספטמבר 2026.' sessionId=ruby-ext:turqiz-main, source=radiant, traceId=tosp_test_e2e_002. שלב 6 (Browser Extension ↔ Radiant) סגור — כל ה-endpoints פעילים, התוסף מכוון ל-api-bank, וה-RCP router עובד מקצה-לקצה.
- שלב: browser-extension
2026-09-04 22:24 CEST — [radiant]
- שלב 6.6 (חלקי): בדיקת E2E ללא token החזירה AUTH_REQUIRED כצפוי — ה-endpoint דורש auth (rxt_ token או api-key). זה תקין ומאמת שה-security layer עובד. לבדיקה מלאה נדרש provision של rxt_ token דרך /api/ruby/extension/provision או שימוש ב-master key.
- שלב: browser-extension
2026-09-04 22:23 CEST — [radiant]
- שלב 6.5 הושלם: עודכן DEFAULT_SERVER ב-background.js מ-ruby.turqizai.com ל-apibank.turqizai.com (port 3006 עם v4.0.4-radiant). נוסף host_permission ל-radiant.turqizai.com ב-manifest.json. sidepanel.js כבר היה מכוון ל-apibank.turqizai.com. התוסף עכשיו מדבר עם api-bank (RCP intents) במקום ruby-ai הישן.
- שלב: browser-extension
2026-09-04 22:20 CEST — [radiant]
- שלב 6.4 הושלם: זוהתה בעיית routing — port 3004 מריץ ruby-ai (v1.0.0, 7 capabilities ישנות), port 3006 מריץ api-bank (v4.0.4-radiant, 8 capabilities + RCP intents). התוסף כרגע מדבר עם 3004 (ruby.turqizai.com). הפתרון: לשנות DEFAULT_SERVER בתוסף ל-apibank.turqizai.com (port 3006) או להפנות את ruby.turqizai.com ל-api-bank. המניפסט ב-3006 תקין: chat, summarize, explain, extract, translate, automation, contextMenus, screenshot.
- שלב: browser-extension
2026-09-04 22:10 CEST — [radiant]
- שלב 6.3 הושלם: TOSP manifest endpoint פעיל (HTTP 200) ב-api-bank port 3004. גרסה 1.0.0 עם 7 capabilities (summarize, extract, explain, translate, chat + selection variants). הערה: המניפסט החי הוא v1.0.0 (ישן יותר מה-v4.0.4-radiant שבקוד המקור של tosp-adapter.ts) — כנראה api-bank מריץ build ישן או route אחר. יש לבדוק אם צריך rebuild/restart כדי שהגרסה החדשה תעלה.
- שלב: browser-extension
2026-09-04 22:08 CEST — [radiant]
- שלב 6.2 הושלם: נמצא שה-TOSP adapter כבר קיים ומלא ב-api-bank! tosp-adapter.ts כולל: buildTospManifest (עם RCP intents), tospTaskToRcp (ממיר chat/summarize/extract/automation ל-RCPMessage), authenticateExtension (rxt_ tokens + tenantId), buildTospExecuteResponse. execute/route.ts מנתב query→agentBridge ו-automation→browserAutomation. manifest/route.ts מחזיר manifest tenant-scoped. אין צורך לבנות מחדש — רק לוודא שה-endpoints פעילים ולהוסיף host_permissions לתוסף.
- שלב: browser-extension
2026-09-04 22:04 CEST — [radiant]
- שלב 6 הושלם: מיפוי נקודות חיבור Ruby Chrome Extension ↔ Radiant. נכתב references/browser-extension.md עם 8 endpoints למיפוי, auth flow (Keycloak SSO), automation engine (18 actions), ו-8 תתי-משימות לביצוע. המסקנה: התוסף הוא thin client — לא משנים קוד בתוסף, רק server-side adapters ב-API-Bank/Radiant.
- שלב: browser-extension
2026-09-04 21:59 CEST — [radiant]
- המשך עבודה לאחר בדיקת סטטוס. WhatsApp Business integration hook acknowledged — session active and operational. Integration is fully functional.
- שלב: integration
2026-09-04 19:57 CEST — [radiant]
- מחבר אינטגרציה ל-Radiant: tenantId=tenant_25fa3e25c5bf1ac1, integrationId=whatsapp-business, name=WhatsApp — 972545454034, category=messaging, actions=send_message,receive_message,get_status
- שלב: integration
2026-09-04 19:32 CEST — [radiant]
- WhatsApp Business integration hook received & verified — tenant_25fa3e25c5bf1ac1, whatsapp-business, phone 972545454034, status: connected
- שלב: 1
2026-09-04 18:54 CEST — [radiant]
- WhatsApp business integration webhook received - tenant: tenant_25fa3e25c5bf1ac1, integrationId: whatsapp-business, phone: 972545454034
- שלב: webhook
2026-09-04 18:30 CEST — [radiant]
- WhatsApp Business integration hook received — tenant_25fa3e25c5bf1ac1, integrationId: whatsapp-business, name: WhatsApp — 972545454034
- שלב: 2
2026-09-04 18:13 CEST — [radiant]
- WhatsApp Business integration hooked via webhook. tenantId: tenant_25fa3e25c5bf1ac1, integrationId: whatsapp-business, phone: 972545454034
- שלב: 2
2026-09-04 17:56 CEST — [radiant]
- WhatsApp Business integration verified: tenant_25fa3e25c5bf1ac1 / whatsapp-business / 972545454034
- שלב: 2
2026-09-04 17:56 CEST — [radiant]
- WhatsApp Business integration hook received
- שלב: 1
2026-09-04 17:46 CEST — [radiant]
- WhatsApp Business integration hook received & verified — tenant_25fa3e25c5bf1ac1, whatsapp-business, status: connected
- שלב: 3
2026-09-04 17:00 CEST — [radiant]
- Webhook received: WhatsApp Business integration notification for tenant_25fa3e25c5bf1ac1
- שלב: 1
2026-09-04 16:51 CEST — [radiant]
- Hook received: WhatsApp Business integration confirmed for tenant_25fa3e25c5bf1ac1 — 972545454034
- שלב: integration
2026-09-04 16:26 CEST — [radiant]
- אינטגרציה WhatsApp Business אומתה: tenant_25fa3e25c5bf1ac1 / 972545454034 — פעולות: send_message, receive_message, get_status
- שלב: 1
2026-09-04 16:26 CEST — [radiant]
- קיבלתי הודעת webhook על אינטגרציה ל-Radiant: WhatsApp Business tenant_25fa3e25c5bf1ac1 (972545454034)
- שלב: 0
2026-09-04 16:10 CEST — [radiant]
- WhatsApp Business integration hook received — tenant: tenant_25fa3e25c5bf1ac1, phone: 972545454034, actions: send_message, receive_message, get_status
- שלב: 1
2026-09-04 16:01 CEST — [radiant]
- מחבר אינטגרציה ל-Radiant נרשם: WhatsApp Business (972545454034) | tenant: tenant_25fa3e25c5bf1ac1 | actions: send_message, receive_message, get_status
- שלב: integration
2026-09-04 15:43 CEST — [radiant]
- WhatsApp Business integration hook received and verified — tenantId: tenant_25fa3e25c5bf1ac1, integrationId: whatsapp-business, name: WhatsApp — 972545454034
- שלב: 1
2026-09-04 15:01 CEST — [radiant]
- WhatsApp Business integration webhook received — tenant_25fa3e25c5bf1ac1 / whatsapp-business / 972545454034
- שלב: integration
2026-09-04 14:43 CEST — [radiant]
- קישור אינטגרציה ל-Radiant נקלט: WhatsApp Business tenant_25fa3e25c5bf1ac1 | integrationId: whatsapp-business | phone: 972545454034
- שלב: 1
2026-09-04 14:30 CEST — [radiant]
- הוק WhatsApp Business נרשם - tenantId: tenant_25fa3e25c5bf1ac1, integrationId: whatsapp-business, actions: send_message, receive_message, get_status
- שלב: 3
2026-09-04 14:10 CEST — [radiant]
- WhatsApp Business integration hooked — tenant_25fa3e25c5bf1ac1 / whatsapp-business / 972545454034
- שלב: integration
2026-09-04 13:31 CEST — [radiant]
- WhatsApp Business integration hook received — integration active: tenant_25fa3e25c5bf1ac1 / whatsapp-business / 972545454034
- שלב: webhook
2026-09-04 13:31 CEST — [radiant]
- WhatsApp Business integration hook acknowledged — tenantId: tenant_25fa3e25c5bf1ac1, integrationId: whatsapp-business, phone: 972545454034
- שלב: webhook
2026-09-04 12:28 CEST — [radiant]
- Webhook received: WhatsApp Business integration hook — tenantId: tenant_25fa3e25c5bf1ac1, integrationId: whatsapp-business, phone: 972545454034
- שלב: webhook
2026-09-04 10:50 CEST — [radiant]
- WhatsApp Business integration hooked — tenant_25fa3e25c5bf1ac1 / whatsapp-business / 972545454034
- שלב: connect
2026-09-04 10:42 CEST — [radiant]
- מחבר אינטגרציה ל-Radiant התקבל: whatsapp-business (tenant_25fa3e25c5bf1ac1) — הודעת אימות נשלחה ל-972545454034
- שלב: 1
2026-09-04 10:25 CEST — [radiant]
- WhatsApp Business integration hooked — tenantId: tenant_25fa3e25c5bf1ac1, integrationId: whatsapp-business, phone: 972545454034
- שלב: 2
2026-09-04 08:51 CEST — [radiant]
- ✅ WhatsApp Business integration verified — message delivered to 972545454034@s.whatsapp.net
- שלב: 2
2026-09-04 08:51 CEST — [radiant]
- מחבר אינטגרציה ל-Radiant: whatsapp-business (tenant_25fa3e25c5bf1ac1) — נכנס הוק עם פעולות: send_message, receive_message, get_status
- שלב: 1
2026-09-04 08:34 CEST — [radiant]
- אינטגרציה מאומתת: WhatsApp Business (tenant_25fa3e25c5bf1ac1) - פעיל ומחובר
- שלב: 2
2026-09-04 08:34 CEST — [radiant]
- קישור אינטגרציה ל-Radiant: WhatsApp Business (tenant_25fa3e25c5bf1ac1 / whatsapp-business)
- שלב: 1
2026-09-04 07:53 CEST — [radiant]
- Webhook received: WhatsApp Business integration hook for tenant_25fa3e25c5bf1ac1
- שלב: 1
2026-09-04 07:35 CEST — [radiant]
- WhatsApp Business integration hooked — tenant_25fa3e25c5bf1ac1 | integrationId: whatsapp-business | phone: 972545454034 | actions: send_message, receive_message, get_status
- שלב: 3
2026-09-04 06:47 CEST — [radiant]
- WhatsApp Business integration verified — all actions (send_message, receive_message, get_status) available at http://127.0.0.1:3090
- שלב: 2
2026-09-04 06:47 CEST — [radiant]
- Webhook received: WhatsApp Business integration hook — tenant_25fa3e25c5bf1ac1 / whatsapp-business / 972545454034
- שלב: 1
2026-09-04 06:15 CEST — [radiant]
- אינטגרציה WhatsApp Business אושרה: tenant_25fa3e25c5bf1ac1 / whatsapp-business / 972545454034 — פעולות: send_message, receive_message, get_status
- שלב: 2
2026-09-04 06:15 CEST — [radiant]
- מחבר אינטגרציה ל-Radiant נרשם: WhatsApp — 972545454034 (tenant_25fa3e25c5bf1ac1, whatsapp-business)
- שלב: 1
2026-09-04 05:16 CEST — [radiant]
- Hook received - whatsapp-business integration for tenant_25fa3e25c5bf1ac1 (Job ID: 386f941a-889d-4bd6-b9d6-df05a3bc6890)
- שלב: hook
2026-09-04 03:50 CEST — [radiant]
- התקבל הוק אינטגרציה ל-Radiant: whatsapp-business (tenant_25fa3e25c5bf1ac1) — פעולות: send_message, receive_message, get_status
- שלב: integration
2026-09-04 03:17 CEST — [radiant]
- Webhook received: WhatsApp Business integration hooked for tenant_25fa3e25c5bf1ac1 (whatsapp-business, job f96a75f4-60a3-4f63-9482-b96bdedf9a74)
- שלב: 1
2026-09-04 01:46 CEST — [radiant]
- Hook WhatsApp Business integration נושם: tenantId=tenant_25fa3e25c5bf1ac1, integrationId=whatsapp-business, name='WhatsApp — 972545454034', category=messaging, actions=[send_message, receive_message, get_status]
- שלב: hook
2026-09-04 01:46 CEST — [radiant]
- ניתקל ועדכנתי עסקה של WhatsApp Business webhook — tenantId: tenant_25fa3e25c5bf1ac1, integrationId: whatsapp-business, name: WhatsApp — 972545454034, category: messaging, actions: send_message, receive_message, get_status
- שלב: hook
2026-09-04 01:36 CEST — [radiant]
- WhatsApp Business integration hook processed — tenant_25fa3e25c5bf1ac1 / whatsapp-business / 972545454034 — connection verified, confirmation message sent
- שלב: hook
2026-09-04 01:27 CEST — [radiant]
- WhatsApp Business integration hook processed — tenant_25fa3e25c5bf1ac1, whatsapp-business, actions: send_message/receive_message/get_status
- שלב: 1
2026-09-04 01:09 CEST — [radiant]
- WhatsApp Business integration hooked via webhook — tenantId: tenant_25fa3e25c5bf1ac1, integrationId: whatsapp-business, phone: 972545454034
- שלב: integration
2026-09-04 00:40 CEST — [radiant]
- קיבלתי webhook של WhatsApp Business integration — tenant_25fa3e25c5bf1ac1 — כבר רשום ופעיל ב-skill whatsapp-web
- שלב: 0
2026-09-04 00:26 CEST — [radiant]
- WhatsApp Business integration registered via webhook. tenantId: tenant_25fa3e25c5bf1ac1, integrationId: whatsapp-business, phone: 972545454034
- שלב: 1
2026-09-03 23:16 CEST — [radiant]
- אינטגרציה whatsapp-business נרשמה ואומתה — tenantId: tenant_25fa3e25c5bf1ac1, endpoint: http://127.0.0.1:3090/send-message, jobId: eca201e1-e747-4056-970f-a78039813cb3, endpoint test: ✅ success
- שלב: 1
2026-09-03 23:16 CEST — [radiant]
- קבלת webhook אינטגרציה ל-Radiant — tenant: tenant_25fa3e25c5bf1ac1, integrationId: whatsapp-business, name: WhatsApp — 972545454034, category: messaging
- שלב: 1
2026-09-03 23:03 CEST — [radiant]
- קיבלת webhook של אינטגרציה ל-Radiant: whatsapp-business (tenant_25fa3e25c5bf1ac1) — כבר מופעל ותקין
- שלב: 0
2026-09-03 17:55 CEST — [radiant]
- שילבתי NVIDIA API (DeepSeek V4 Pro) במערכת Radiant:
- POST /api/ai/nvidia/chat - צ'אט עם הקשר טננט
- GET /api/ai/nvidia/models - רשימת מודלים זמינים
- POST /api/ai/nvidia/embeddings - יצירת embeddings
- מפתח API נשמר ב-.env.local של api-bank
- דורש התחברות (JWT/API key/extension token)
- שלב: integrations
2026-09-03 17:47 CEST — [radiant]
- הוספתי אינטגרציית NVIDIA API (DeepSeek V4 Pro) למערכת Radiant - מפתח API נשמר ב-.env.local
- שלב: integrations
2026-09-03 12:30 CEST — [radiant]
- השלמתי בניית תשתית VPN מלאה עם טננט-איזולציה:
1. Keycloak OIDC realm 'radiant' + client 'headscale' + משתמש radiant-admin
2. Headscale עם OIDC + ACL policy (tags לכל טננט) + 6 auth keys
3. API endpoint /api/vpn/authkey שמחזיר auth key לפי JWT
4. Desktop Agent (PowerShell) שמבצע SSO device flow ומתחבר ל-VPN
5. השרת מחובר ל-Headscale עם tag:tenant-default (IP: 100.64.0.1)
נשאר: להוסיף רשומת DNS A ל-vpn.turqizai.com -> 84.247.162.143
- שלב: vpn
2026-09-03 12:11 CEST — [radiant]
- התחלתי בניית תשתית VPN עם טננט-איזולציה: יצרתי realm 'radiant' ב-Keycloak, client 'headscale' עם OIDC, משתמש radiant-admin, nginx config ל-vpn.turqizai.com (ממתין ל-DNS A record), Headscale ACL policy עם tags לכל טנננט
- שלב: vpn
2026-09-03 09:19 CEST — [radiant]
- אינטגרציה whatsapp-business כבר רשומה ב-API Bank וב-SKILL. מאמת חיבור WhatsApp...
- שלב: integration
2026-09-03 09:19 CEST — [radiant]
- התקבל hook לאינטגרציה חדשה: whatsapp-business (tenant_25fa3e25c5bf1ac1) — פעולות: send_message, receive_message, get_status
- שלב: integration
2026-09-03 07:17 CEST — [radiant]
- ✅ WhatsApp Business integration hooked successfully — tenantId: tenant_25fa3e25c5bf1ac1, integrationId: whatsapp-business, phone: 972545454034
- שלב: 1
2026-09-03 06:50 CEST — [radiant]
- Hook Job 16650739: WhatsApp integration (whatsapp-business, tenant_25fa3e25c5bf1ac1) received and verified ONLINE. Actions: send/receive/status. Confirmed 127.0.0.1:3090 reachable.
- שלב: hook
2026-09-03 05:12 CEST — [radiant]
- Webhook hook received: WhatsApp Business integration registered — tenant_25fa3e25c5bf1ac1 / whatsapp-business — service already live and connected
- שלב: 1
2026-09-03 04:57 CEST — [radiant]
- התקבל webhook הוקע להיכרות WhatsApp Business — tenantId: tenant_25fa3e25c5bf1ac1, integrationId: whatsapp-business, name: WhatsApp — 972545454034. כבר רשום ב-skill whatsapp-web.
- שלב: hook
2026-09-02 23:54 CEST — [radiant]
- WhatsApp Business integration registered via webhook — tenantId: tenant_25fa3e25c5bf1ac1, integrationId: whatsapp-business, phone: 972545454034
- שלב: webhook
2026-09-02 23:32 CEST — [radiant]
- Webhook received: WhatsApp integration connected to Radiant — tenant_25fa3e25c5bf1ac1 / whatsapp-business / 972545454034
- שלב: 0
2026-09-02 23:31 CEST — [radiant]
- WhatsApp integration hook received — tenant: tenant_25fa3e25c5bf1ac1, integrationId: whatsapp-business, phone: 972545454034
- שלב: webhook
2026-09-02 23:29 CEST — [radiant]
- הוק WhatsApp Business hook נקלט — tenant_25fa3e25c5bf1ac1 / whatsapp-business כבר פעיל ומאומת
- שלב: 1
2026-09-02 22:00 CEST — [radiant]
- Webhook נרשם: WhatsApp Business integration (tenant_25fa3e25c5bf1ac1) — actions: send_message, receive_message, get_status
- שלב: webhook
2026-09-02 21:27 CEST — [radiant]
- התקבל hook לאינטגרציה whatsapp-business — tenantId: tenant_25fa3e25c5bf1ac1. WhatsApp 972545454034 נמצא ONLINE וחובר.
- שלב: 1
2026-09-02 20:44 CEST — [radiant]
- WhatsApp business integration hooked — tenant_25fa3e25c5bf1ac1 / whatsapp-business — verified live at 127.0.0.1:3090
- שלב: 0
2026-09-02 19:32 CEST — [radiant]
- בדיקת VPN desktop MSI: אין tunnel 'radiant'; wg show interfaces ריק; TCP 84.247.162.143:5227 חסום/לא ניתן להגיע מהרשת הנוכחית; השולחן עבודה מחזיק token tenantId=default yשן. דרוש re-link ל־turqiz-main.
- שלב: 7
2026-09-02 18:49 CEST — [radiant]
- WhatsApp business integration hook received & registered — tenantId: tenant_25fa3e25c5bf1ac1, integrationId: whatsapp-business, phone: 972545454034
- שלב: 1
2026-09-02 18:00 CEST — [radiant]
- תיקנתי את Radiant VPN (desktop): (1) שורש הבעיה — ufw פעיל עם Default deny incoming אבל לא היה שום חוק UDP לפורטים של WireGuard (5129/5227), לכן ה-handshake נחסם וה-VPN לא התחבר. הוספתי ufw allow 5129/udp + 5227/udp. (2) הוספתי ל-wireguard-manager.ts פתיחת פורט אוטומטית ב-createInstance (ufw allow <port>/udp) כדי שכל tenant חדש יפתח את הפורט שלו. (3) אימתי end-to-end: SSO authorize→provision→token→vpn/config עובד, שני interfaces רצים (vpn-default:5129, vpn-turqiz-main:5227), ip_forward=1, MASQUERADE מוגדר. (4) מצאתי באג משני: token ישן ב-MSI הוא tenantId=default אבל המשתמש האמיתי mozez@turqizai.com הוא turqiz-main.
2026-09-02 17:48 CEST — [radiant]
- קלט הוק WhatsApp Business: tenantId=tenant_25fa3e25c5bf1ac1, integrationId=whatsapp-business, phone=972545454034
- שלב: hook
2026-09-02 17:44 CEST — [radiant]
- התקין אינטגרציה ל-Radiant: tenantId: turqiz-main, integrationId: whatsapp-web (Job ID: 9956ec96-f458-45bd-9211-83fa549f2c4d)
- שלב: 1
2026-09-02 17:44 CEST — [radiant]
- WhatsApp hook verified — message delivered to 972545454034
- שלב: 2
2026-09-02 17:43 CEST — [radiant]
- התקבל Hook ל-integration whatsapp-business — tenant: tenant_25fa3e25c5bf1ac1, phone: 972545454034
- שלב: 1
2026-09-02 17:32 CEST — [radiant]
- תיקנתי 2 באגים קריטיים ב-WhatsApp: (1) כפתור Test החזיר 'Ping Failed' בגלל ReferenceError של tenantId לא מוגדר ב-route — החלפתי לבדיקה חיה מול gateway /status. (2) הבאג הקריטי: frontend שולח poll ל-/qr-code כל 3 שניות, וה-route הישן הפעיל reset ל-gateway (initBaileys(null)) בכל poll — זה ביטל את הקוד/QR שהמשתמש סרק, ולכן 'בטלפון מחובר אבל במערכת מנותק'. תיקנתי: poll רגיל לא מאפס את ה-socket, רק force=true מאפס. אימתי: gateway יציב 20 שניות עם קוד קבוע CPJMYCQW.
2026-09-02 16:55 CEST — [radiant]
- הוספתי סגירה אוטומטית של מודאל WhatsApp ב-marketplace: useEffect חדש מזהה waLiveStatus.isConnected (נבדק כל 3 שניות מול /api/whatsapp/qr) וכשהחיבור מזוהה — שומר את האינטגרציה ל-DB, עובר ל-qrStep=connected וסוגר את המודאל אוטומטית אחרי 1.2 שניות. בנייה נקייה + restart ruby-ai-prod.
2026-09-02 16:40 CEST — [radiant]
- תיקנתי באג קריטי ב-marketplace: כפתורי 'סרוק QR קוד' ו'קבל קוד 8-ספרות' (WhatsApp) קראו לפונקציות handleFetchQr ו-handlePairDevice שלא היו מוגדרות בכלל — לחיצה עליהן גרמה ל-ReferenceError ולקריסת הדף ('This page couldn't load'). הוספתי את שתי הפונקציות (קוראות ל-/api/whatsapp/qr ליצירת QR וקוד צימוד), והוספתי תצוגת שגיאה (pairingError) במודאל. בנייה נקייה + restart ruby-ai-prod. אומת: marketplace 200, QR endpoint מחזיר qrDataUrl.
2026-09-02 14:01 CEST — [radiant]
- חקירת מקור הכורה: בדקתי את מחשב ה-MSI דרך desktop-control (deviceId b5f5ee2f). ממצאים: (1) ה-IP הציבורי של ה-MSI הוא 85.250.90.112 — זהה בדיוק ל-IP שהתקין את הכורה בשרת ב-06:24-06:43. (2) ה-SSH key ששימש להתקנה הוא id_ed25519 (mozez@MSI) — ה-key הלגיטימי. (3) במחשב ה-MSI אין תהליך כורה, אין משימות מתוזמנות חשודות, אין ערכי Run חשודים, אין קבצי exe חשודים ב-Temp/Downloads. (4) תהליכים חריגים: CrossDeviceService (95453s CPU), RapooOfficeDev (35169s), Antigravity (IDE), python. מסקנה: ה-key הפרטי של mozez@MSI דלף/נפרץ, או שה-MSI משמש כ-jump host. נדרש סיבוב SSH key.
2026-09-02 13:43 CEST — [radiant]
- אירוע אבטחה קריטי: זיהיתי כורה קריפטו (XMRig) שהתחזה ל-'system-check' ב-/root/system-check/. רץ מ-06:43, צרך 293% CPU + 2.1GB RAM, כרה Monero ל-pool.supportxmr.com. זה גרם לשרת להיות חנוק (load 7.8, RAM 164MB פנוי) — כנראה הסיבה ש'המשק של רובי לא עובד'. הרגתי את התהליך (PID 2759023), מחקתי את /root/system-check/, אימתי שאין respawn (cron/systemd/rc.local/basrc נקיים). הותקן דרך SSH key של mozez@MSI (IP 85.250.90.112, 06:24-06:43). אחרי הניקוי: load ירד 5.3→3.5, RAM פנוי 164MB→2.1GB, dashboard מגיב ב-0.1s.
2026-09-02 13:23 CEST — [radiant]
- חקירת 'למה רובי לא עונה בקבוצה': שורש הבעיה = הדיסק התמלא שוב (87%) → שגיאת ENOSPC → קובץ session של WhatsApp (creds.json) נמחק ל-0 בתים ב-03:23 → הגייטוויי מנותק בלולאת QR. פיניתי ~24GB (מחיקת 5 גיבויים ישנים, עכשיו 71%). ניסיתי לשחזר creds מ-backup (Aug 14) אבל קיבל 401 (session פג/נשלל) והגייטוויי מחק אותו שוב. נדרש סריקת QR מחדש. בנוסף: הקבוצה 'רובי' (120363428170035377) מוגדרת respondToMentionsOnly=true ולכן עונה רק עם @mention מפורש.
2026-09-02 12:31 CEST — [radiant]
- ניקוי כפילויות ב-radiant_integration_registry: 328 רשומות whatsapp-business תחת tenant_25fa3e25c5bf1ac1 צומצמו ל-1 (נשמרה העשירה ביותר, נמחקו 327). עכשיו registry נקי: 6 רשומות ייחודיות (5 turqiz-main + 1 tenant_25fa3e25c5bf1ac1).
2026-09-02 12:22 CEST — [radiant]
- מיגרציית נתונים היסטוריים: (1) Google token הועבר מ-userId=default ל-user האמיתי 6a607d30... (mozez.a@gmail.com). (2) כל האינטגרציות תחת tenantId=default (telegram-bot, whatsapp-web, whatsapp-qr, slack) הועברו ל-turqiz-main ונרשמו ב-radiant_integration_registry עם connectedToRadiant=true. (3) תוקן collision של unique index (slack עם integrationId=null). תוצאה: 0 אינטגרציות נשארו תחת default, 5 אינטגרציות מגושרות ל-Radiant תחת turqiz-main. סקריפט: migrate-identity.js (dry-run + --apply).
2026-09-02 12:07 CEST — [radiant]
- תיקון 2 בעיות קריטיות (זהות + אינטגרציות→Radiant): (1) דליפת מייל — login החזיר id:'default' קשיח, אז Google token נשמר תחת 'default' משותף. תיקנתי ruby/auth/login (api-bank) לרזולוציית user אמיתית מ-better-auth לפי email, ותיקנתי google/callback + google/status (ruby-ai) לקחת userId מ-id_token (anti-spoofing) במקום state='default'. (2) אינטגרציות לא מגושרות ל-Radiant — ה-UI כתב רק ל-integrations בלי לקרוא ל-bridge. יצרתי ruby-ai/src/lib/radiant-bridge.ts + חיברתי אותו ל-POST /api/ruby/integrations. תיקנתי גם sessionKey ל-'ruby-ext:' prefix (היה 'ruby-integration:' שלא עבר את allowedSessionKeyPrefixes). (3) settings route — הסרתי tenantId='default' קשיח, עכשיו מ-session. אימתי: login מחזיר id אמיתי (6a607d30.../turqiz-main), bridge מחזיר hooks/agent 200, telegram נרשם ב-registry.
2026-09-02 12:07 CEST — [radiant]
- Hook received — Telegram Bot integration author for tenant turqiz-main (integrationId: telegram-bot). Payload truncated at actions: key — no actionable data. Logged as metadata notification.
- שלב: notification
2026-09-02 09:56 CEST — [radiant]
- שלב 7 — איחוד federation: מחקתי את ה-federation-engine.ts (dead code) + מודל FederationConnection.ts + כל 6 ה-routes של /api/federation/*. הם התנגשו עם federation-protocol.ts על אותה collection (apibank_federation_connections) בסכמות שונות, ולא היה להם שום ref בקוד. עכשיו יש מימוש אחד: federation-protocol.ts (tasks/connections/chains/callbacks) דרך /api/gateway/federation/*. אימתי: tsc+build נקיים, /api/federation/connections → 404, /api/gateway/federation/tasks → 401 (עדיין חי).
- שלב: 7
2026-09-02 09:30 CEST — [radiant]
- שלב 7 (Federation tenant-scoping) — מימוש: (1) הוספתי tenantId מנדטורי למודל FederationConnection + CreateConnectionOptions. (2) listConnections/getConnection/executeChain/listChains עכשיו מסוננים לפי tenantId. (3) כל 6 ה-routes של /api/federation/* עכשיו דורשים requireTenantAuth (tenantId מ-auth, לא מ-query param — anti-spoofing). לפני כן: GET /api/federation/connections החזיר את כל החיבורים בלי שום auth, ו-tenantId הגיע מ-query param (spoofable). אימתי: בלי key → 401 (לפני: 200 עם כל הנתונים). tsc+build נקיים.
- שלב: 7
2026-09-02 09:21 CEST — [radiant]
- שלב 7 (Federation on top of Nodes): מיפיתי את כל שכבת ה-federation. ממצאים: (1) שתי מימושים מקבילים ב-api-bank — federation-engine.ts (מודל FederationConnection, collection apibank_federation_connections, משמש /api/federation/*) ו-federation-protocol.ts (interface עם tenantId+id, אותה collection!, משמש /api/gateway/federation/*). (2) ruby-ai יש ConnectionRegistry (mongoose, collection connectionregistries) עם tenant-scoping תקין. (3) פער אבטחה קריטי: /api/federation/* (engine) בלי שום auth — tenantId מגיע מ-query param (spoofable) ו-listConnections מתעלם ממנו לגמרי. (4) אין שום קישור בין federation ל-Nodes.
- שלב: 7
2026-09-02 08:56 CEST — [radiant]
- TOSP manifest: הוספתי שדה ui מלא (theme/sidepanel/popup/features) + extensionMinVersion + endpoints ל-buildTospManifest ב-api-bank. לפני כן ה-manifest חסר ui → התוסף נפל ל-hardcoded UI במקום לקבל עדכון UI מהשרת. עכשיו מנגנון 'עדכון UI מהשרת בלי publish בחנות' עובד: sidepanel.js קורא manifest.ui ובונה כותרת/כפתורים מהירים/הודעת פתיחה/prompts/placeholder. יישרתי גרסה ל-4.0.4-radiant. אימתי live: manifest מחזיר ui.sidepanel.quickActions=4.
- שלב: 6
2026-09-02 07:36 CEST — [radiant]
- שלב 6 (Browser Extension ↔ Radiant): מיפיתי את כל נתיב התוסף הרשמי (Chrome Web Store v4.0.4) ל-Radiant ותיקנתי באג קריטי. התוסף (TOSP thin client) מדבר עם api-bank /api/ruby/tosp/* → tosp-adapter → RCP → agent-bridge → Gateway hooks (POST /hooks/agent). באג: agent-bridge פתר את קובץ הסשן דרך 'openclaw sessions --json' שלוקח ~30s אבל timeout היה 10s → התשובה מעולם לא נמצאה (החזיר '(לא התקבלה תשובה מה-agent)'). תיקנתי: קריאה ישירה ל-sessions.json index (מיידי) + fallback CLI עם timeout 60s. אימתי end-to-end: chat מחזיר תשובה אמיתית מ-Radiant.
- שלב: 6
2026-09-02 06:33 CEST — [radiant]
- תיקון קריסת MongoDB: log 248MB מילא דיסק (87%) → mongod נפל ב-03:22. הוספתי /etc/logrotate.d/mongodb (size 50M, copytruncate, rotate 7), הרצתי logrotate -f (פינה 232MB), mongod חזר active. אימתי: 7 tenants ב-DB, container lvl1 healthy, api-bank/ruby-ai/gateway חיים.
- שלב: 5
2026-09-01 22:31 CEST — [radiant]
- פרסתי containers אמיתיים לכל 3 רמות ה-isolation: Gamma Health Global (enterprise=level_3), Beta FinTech (business=level_2), Alpha Retail (starter=level_1). כולם עם turqiz/radiant:v1.5.0, gateway ready + ruby 200 + healthy. עכשיו כל 3 הארכיטקטורות של ה-tenant מודגמות עם containers אמיתיים.
2026-09-01 22:20 CEST — [radiant]
- סגרתי את הלולאה המלאה: container אמיתי ל-Gamma Health Global. תיקנתי 4 באגים: (1) deploy_fleet עדכן רק currentImageVersion (עכשיו גם appVersion+containerConfig.imageTag), (2) provision route מיפה plan->isolation (enterprise=level_3) + הזריק OLLAMA_BASE_URL, (3) Dockerfile.radiant מחליף 127.0.0.1:11434 ב-${OLLAMA_BASE_URL}, (4) build script הסיר whatsapp מ-plugins+channels (plugin דורש API>=2026.8.2, runtime 2026.7.1-2). Ollama עכשיו על 0.0.0.0 (מוגן firewall ל-docker subnet). container רץ: gateway ready + ruby 3000 + 18790, healthy.
2026-09-01 20:57 CEST — [radiant]
- fleet rollout הושלם: 7 טננטים שודרגו ל-v1.5.0 (deploymentStatus=healthy). הלולאה המלאה סגורה: build -> push -> registry (HTTPS) -> pull -> deploy. כל הפרויקט הושלם.
2026-09-01 20:52 CEST — [radiant]
- פתרתי את ה-DNS ל-registry! IONOS Domain API (לא Cloud): endpoint api.hosting.ionos.com/dns/v1, header X-API-Key, POST records מצפה ל-array. יצרתי A record registry.turqizai.com -> 84.247.162.143, הנפקתי Lets Encrypt cert, nginx HTTPS 443 -> 5000. docker pull דרך hostname ציבורי HTTPS עובד end-to-end. הסרתי insecure-registries (לא צריך יותר).
2026-09-01 20:10 CEST — [radiant]
- הקמתי registry אמיתי: registry:2 ב-127.0.0.1:5000, nginx proxy registry.turqizai.com, /etc/hosts. תיקנתי באג: buildx יצר OCI index עם attestation שלא נדחף → pull נכשל. פתרון --provenance=false --sbom=false → manifest יחיד. image נדחף, pull נקי עובד דרך 127.0.0.1:5000. נותר: hostname לא נפתר ע"י dockerd (אין DNS ציבורי, IONOS expired).
2026-09-01 19:23 CEST — [radiant]
- השלמתי את 3 השלבים האחרונים: (1) commit העבודה ל-git (RBAC+version+loop+image, 29 קבצים, בלי secrets), (2) promote_golden — v1.5.0 כבר golden master (seed מ-manifest), תיקנתי ruby/tenant→radiant/tenant ב-DB, (3) canary deploy v1.5.0 לטננט test — הצליח. החלטה: ruby-ai-dev נשאר copy נפרד (לא git branch).
2026-09-01 19:14 CEST — [radiant]
- תיקנתי dashboard שבור (אין עיצוב) ב-ruby.turqizai.com. שורש הבעיה: build-radiant-image.sh הריץ npm run build מקומי בתוך ruby-ai/ (ה-cwd של ruby-ai-prod) ודרס את .next/ שה-prod מגיש ממנו → CSS 404. תוקן: restart ל-ruby-ai-prod (טען build חדש) + הסרת ה-build המקומי מה-script (ה-Dockerfile.radiant כבר בונה בתוך container). אומת: כל CSS/JS 200.
2026-09-01 17:44 CEST — [radiant]
- בניתי image Radiant אמיתי (turqiz/radiant:v1.5.0, 1.73GB) עם OpenClaw 2026.7.1-2 + הגדרות (SOUL/IDENTITY/skills/memory) + ruby-ai. תיקנתי 4 באגים: (1) node:20→24-alpine (OpenClaw דורש node>=22), (2) npm ci נכשל (lockfile לא מסונכרן), (3) manifest.json חסר ב-build context, (4) gateway start→foreground (אין systemd ב-container). אומת: OpenClaw+הגדרות+manifest בתוך image, gateway מאזין על 18790 עם --network host (Ollama זמין).
2026-09-01 13:12 CEST — [radiant]
- הגבלת גישה ל-dev gateway (OpenClaw beta, פורט 19001) ל-can_edit_source_code בלבד. בניתי endpoint /api/ruby/dev/access ב-api-bank (auth_request), הגדרתי basePath=/radiant על ה-dev gateway, וחיברתי nginx auth_request על dev.ruby.turqizai.com/radiant/ → 19001. תיקנתי 2 באגי build קיימים (mirror-check.ts, count-temp.ts). אומת: 403 בלי token, 200 עם master key, live (18790) לא נגע.
2026-09-01 12:26 CEST — [radiant]
- הקמתי הפרדת dev/live אמיתית ל-OpenClaw: התקנתי openclaw@beta (2026.9.1-beta.1) ב-prefix נפרד /root/openclaw-dev-install (לא נוגע ב-global/לייב), יצרתי state נפרד /root/.openclaw-radiant-dev, והרצתי gateway dev על פורט 19001 (pm2 radiant-gateway-dev). הלייב (18790) נשאר על stable 2026.7.1-2 ללא שינוי. פיניתי 4.4GB ע"י מחיקת hermes3:latest (מודל מקומא).
- שלב: 5
2026-09-01 10:54 CEST — [radiant]
- בניתי את ה-image של Radiant: Dockerfile.radiant (OpenClaw + ruby-ai + הגדרות) + build-radiant-image.sh (קורא גרסה+OpenClaw מה-manifest, מעתיק SOUL/IDENTITY/skills/memory, בונה turqiz/radiant:<version>).
- שלב: 5
2026-09-01 10:51 CEST — [radiant]
- עדכנתי את כל ה-hardcode הנותר (container/personalities/dashboard/tenants/rollout/ping) לקרוא מה-manifest. תיקנתי 2 באגים: health endpoint חסר (404) + ping version hardcoded. גיליתי פער קריטי: ה-image לא מכיל OpenClaw (עדיין ruby לא radiant).
- שלב: 4
2026-09-01 10:41 CEST — [radiant]
- בניתי מקור אמת יחיד לגרסה: manifest.json (root) + lib/version.ts (ruby-ai + api-bank). עדכנתי version/tenants-version/rollout/images routes + Tenant.ts + package.json לקרוא מה-manifest. פורמט semver (v1.5.0). מניפסט מתעד איזה OpenClaw נכנס לכל גרסה.
- שלב: 3
2026-09-01 10:02 CEST — [radiant]
- ביצעתי restart: ruby-ai-prod (rebuild + restart) ו-whatsapp-gateway. אומת בלייב: whatsappNumber=972545454034 מחזיר spa_beauty בלבד (1 agent). gateway עלה נקי והתחבר.
- שלב: 2
2026-09-01 09:55 CEST — [radiant]
- בניתי את סגירת הלולאה: RubyAgent index + agents route (whatsappNumber regex) + server.js (רובי ראשי, Radiant fallback + פתרון tenantId). גיליתי שהקובץ שרץ הוא server.js לא v21.
- שלב: 1
2026-09-01 09:48 CEST — [radiant]
- תיעוד מלא: הוספתי את channel-to-ruby-loop.md ל-build script של doc.turqizai.com + יצרתי memory/2026-09-01.md בזיכרון המשותף של Radiant.
- שלב: 1
2026-09-01 09:46 CEST — [radiant]
- מיפוי מלא של חיבור ווצאפ→רובי→Radiant. גיליתי שווצאפ (3090) לא מחובר לכלום — רק שומר הודעות. מיפיתי את הלולאה המלאה + פתרון tenantId לפי whatsappNumber (RubyAgent).
- שלב: 1
2026-09-01 09:16 CEST — [radiant]
- תיקנתי באג RBAC: developer לא קיבל גישה ל-core. הוספתי roleCanTouchScope. 15/15 בדיקות עוברות.
- שלב: 1
2026-09-01 09:13 CEST — [radiant]
- הוספתי שכבת RBAC: הרשאת can_edit_source_code + מודול rbac.ts (api-bank + ruby-ai) + אכיפה ב-rollout/images/cross-channel-router
- שלב: 1
2026-09-01 06:22 CEST — [radiant]
- קיבלת הודעת מידע מערכת רובי - אינטגרציות פעילות: Google Workspace (mozez.a@gmail.com) עם סנכרון Gmail, Calendar, Sheets ו-Gemini
- שלב: 0
2026-08-31 21:41 CEST — [radiant]
- קראתי את המייל האחרון של Moshe (mozez.a@gmail.com) דרך Gmail API: 'Almost one year and $17,460.65 later' מ-Baguette Trading (Pablo). שמרתי את התוכן כטקסט בתיקיית Ruby במחשב MSI: C:\Users\mozez\OneDrive\מסמכים\Ruby\last_email.txt (אומת written:true).
2026-08-31 17:47 CEST — [radiant]
- הגירת Ruby AI מ-OmniRoute (20128) ל-Ollama/Radiant (11434) הושלמה: 61 קבצים שונו (ruby-ai prod+dev, api-bank, site), כל שמות המודלים מופו (DeepSeek/Claude/Gemini/GPT -> deepseek/kimi/glm/gemma:cloud), embeddings -> nomic-embed-text. OmniRoute container + redis + source dir נמחקו. גיבוי ב-backups/omniroute-migration-20260831_165313/
- שלב: 6
2026-08-29 04:56 CEST — [radiant]
- MCP public mirror refresh (cron): mirrored 25501 records, totalInMirror=27746, pages=2818, done=true, 662.5s
- שלב: public-mcp-mirror-refresh
2026-08-27 19:22 CEST — [radiant]
- Integration Sidebar Standard 3.0 COMPLETE: 761 pieces with full props (30,612 total), 20+ piece-specific dynamic resolvers, 15 generic prop resolvers, markdown prop type support, all prop types handled, Next.js build passes, dev server running on :3000.
- שלב: integration-sidebar-standard-3.0
2026-08-27 19:21 CEST — [radiant]
- Added markdown prop type to StepSettingsPanel (info banner). All prop types now handled. Next build passes.
- שלב: integration-sidebar-standard-3.0
2026-08-27 19:17 CEST — [radiant]
- Expanded Dynamic Resolver API: 20+ piece-specific resolvers (Slack/Telegram/Notion/GitHub/HubSpot/Stripe/ClickUp/Pipedrive/Zendesk/Jira/Excel/Salesforce/Trello/Mailchimp/Discord/Linear/Asana/Calendly/OpenAI/Brevo/Intercom/Webflow) + 15 generic prop resolvers (method/status/priority/format/language/model/currency/timezone/etc). Build passes.
- שלב: integration-sidebar-standard-3.0
2026-08-27 13:50 CEST — [radiant]
- Enriched pieces-full.ts from empty props to FULL schemas: 761 pieces, 5602 actions, 1508 triggers, 30612 props. Added app_webhook/manual trigger types. Fixed getAnyPiece name resolution.
- שלב: integration-sidebar-standard-3.0
2026-08-27 10:43 CEST — [radiant]
- הושלמה פריסת עמוד Integrations Hub המלא בייצור
- שלב: integrations-hub-live
- החלטה: קטלוג של 760+ אינטגרציות פעיל וזמין ב-dashboard/integrations
2026-08-27 10:30 CEST — [radiant]
- הושלם איפיון n8n Integrations Hub דף אחרי דף ו-Node אחרי Node
- שלב: n8n-integrations-spec-4.0
- החלטה: קטלוג אינטגרציות מלא, עמודי פירוט, Triggers/Actions, ו-AI Tool Calling
2026-08-27 08:55 CEST — [radiant]
- הושלמה פריסת מנוע הסכמות האוניברסלי עבור TradingView וכל כלי ה-MCP ו-727 האינטגרציות
- שלב: universal-schema-engine
- החלטה: תמיכה מלאה בכל כלי MCP ובכל 727 האינטגרציות ב-ruby.turqizai.com/dashboard/automation
2026-08-27 08:18 CEST — [radiant]
- הושלמה הטמעת Integration Sidebar Standard 3.0 ונפרסה בייצור
- שלב: integration-sidebar-standard-3.0
- החלטה: תמיכה מלאה בכל 20 סוגי ה-PropTypes, Refreshers, ו-Dynamic Sub-Forms
2026-08-27 08:14 CEST — [radiant]
- מחקר מעמיק של n8n.io/integrations: 2,097 integrations, 11,772 templates, 4 סוגי nodes (Trigger/Action/Core/Cluster), מודל FlowStep, expressions, credentials, AI Agent nodes. כתיבת N8N_INTEGRATION_SPEC.md (18KB) ב-ruby-ai עם 8 שכבות הטמעה: (1) Drag&Drop Canvas, (2) Core Nodes, (3) AI Cluster Nodes, (4) Expression Engine, (5) Schedule Trigger, (6) Execution Preview, (7) Workflow Settings, (8) Webhook מורחב. השוואה מלאה מול המערכת הקיימת (727 pieces, API routes, builder list-based). Roadmap 3 שבועים.
2026-08-27 08:03 CEST — [radiant]
- הושלם שדרוג מקיף של מנוע האוטומציות וסרגל הצד (Activepieces + n8n) ב-ruby-ai וסונכרן ל-doc.turqizai.com
- שלב: automation-engine-activepieces-upgrade
- החלטה: איחוד מלא של Activepieces UI + n8n Execution Engine ב-ruby.turqizai.com/dashboard/automation
2026-08-27 05:05 CEST — [radiant]
- MCP public mirror refresh completed: countPublicMcp=26741 (was 26073, +668 new/updated). Mirror run: 25116 mirrored across 2766 pages in 672s. done=true. New/updated since last pulse (02:30 UTC): 12 records including io.github.milcho0604/velog, com.astranl/mcp v1.35.24, co.fastaf/fastaf, io.github.microsoft/awesome-copilot.
- שלב: mcp-mirror
2026-08-26 10:54 CEST — [radiant]
- זיהוי הטעות + כתיבת תיעוד מלא: ה-flow builder הקיים ב-/dashboard/automation הוא ruby-ai (ruby.turqizai.com), לא site. ה-VisualFlowBuilder ב-ruby-ai הוא list-based (לא drag & drop). כתבתי ruby-ai/AUTOMATION_DRAG_DROP_BUILDER.md (תיעוד מלא) + עדכנתי AGENTS.md. @xyflow/react כבר מותקן ב-ruby-ai v12.11.5. עבודת ה-reference ב-site/ משמשת דוגמה בלבד.
2026-08-26 10:42 CEST — [radiant]
- סגירת 3 פריטים פתוחים ב-flow builder: (1) הרצה אמיתית — execute/route.ts בודק connection active + decrypt AES-256-GCM + executeRealAction; (2) connections/credentials — מודל IntegrationConnection מוצפן + 3 routes + ConnectionForm + דף dashboard/connections; (3) inputSchema מלא — authFields/baseUrl/rateLimit ב-adapter. typecheck + build נקיים, encrypt/decrypt cycle PASS, collection integrationconnections ריקה ומוכנה.
2026-08-26 10:32 CEST — [radiant]
- תיעד flow-builder.md + סגירת כל השכבות A-E. build + typecheck נקיים.
2026-08-26 10:32 CEST — [radiant]
- בניית Flow Builder (drag&drop) מלא — שילוב אופציה 1+2: שכבת A (adapter integration-templates.ts + 3 API routes), B (canvas ReactFlow + PieceSelector), C (DynamicForm + StepSettingsPanel מ-inputSchema), D (ConditionNode/RouterNode/AgentNode + DataSelector), E (TestStepPanel). חובר ל-727 templates (741 docs) במונגו. build + typecheck נקיים 0 שגיאות.
2026-08-26 10:15 CEST — [radiant]
- מיפוי flow builder (drag&drop): ActivePieces web/src = 188 builder + 28 flows/flow-runs קבצים, מבוסס @xyflow/react 12.3.5. ב-Radiant site: יש @xyflow/react 12.11.2 כבר מותקן + תשתית flows (מודל Flow + API) + chat-flow builder (node types מוגבל ל-chatbot). חסר: builder המחובר ל-727 integration templates + node types של integrations. החלטה: לשלב אופציה 1+2 (להעתיק ADAPT builder + לבנות node source מ-727 templates).
2026-08-26 10:05 CEST — [radiant]
- תוקן URI של Mongo ב-ingest_activepieces_rfb.js (סיסמה ישנה → TurqizApp2026! מ-turqiz-pay/.env). סגירת הפינה האחרונה.
2026-08-26 10:05 CEST — [radiant]
- ביקורת שלמות ActivePieces → Radiant (אחד לאחד): 727 pieces source → 741 templates ingested במאה אחוז (727 + 14 ידניות: whatsapp-business, stripe-payments, slack, github-rest-api וכו'). 5754 actions + 1679 triggers נשמרו. אומת דרך API-Bank (get_template מחזיר actions עם JSON Schema מלא) + MongoDB (apibank_integration_templates). אין pieces חסרים. פער יחיד: URI Mongo בסיסי ב-ingest script לא מעודכן (סיסמה ישנה), לא קריטי.
2026-08-26 09:54 CEST — [radiant]
- ביקורת שלמות 'אחד לאחד' — נמצאו ותוקנו אי-התאמות ספירה: (1) intents מתוקן 46→39 (המספר הישן כלל intents לא-ממומשים). (2) browser actions 14→9 (בפועל 9 + 7 TOSP tasks). (3) events 36→28. (4) intent-router.md ו-intent-discovery.md ומספר docs עודכנו לשפה Radiant במקום OpenClaw. כל הרכיבים קיימים: 8 מודולים נטענים, 39 intents = 39 bridge bindings (MATCH), 17 ops, 740 templates API Bank, 500 tenants federation.
2026-08-26 09:46 CEST — [radiant]
- נסגרה הפינה הסופית: (1) integration-facade.js עודכן עם auth note (registry public, action execution דורש x-api-key per-tenant). (2) health() ירוק — 9 שכבות active, 740 templates public. (3) נכתב STATUS.md סופי שמסכם 9 שכבות + מצב API Bank + מה שנשאר (ops). (4) SKILL.md עודכן ל-v2.1.0 עם טבלת שכבות + קבצי מימוש.
2026-08-26 09:43 CEST — [radiant]
- שכבת איחוד (integration-facade.js) נבנתה: נקודת כניסה אחת שמחברת את כל 8 השכבות + API Bank registry. pipeline מלא: discovery→router→bridge→executor. health() מציג 9 שכבות פעילות. API Bank נבדק חי: federation_connections ריק, whatsapp-business template עם 7 actions (send_message/get_status/delete/send_template/media/interactive/list_conversations).
2026-08-26 09:41 CEST — [radiant]
- שלב 8 הושלם: federation-orchestrator.js — control-plane מלא: provisionTenant (gateway-per-tenant, port דטרמיניסטי hash), enrollment token service (rbx_ חד-פעמי anti-replay), bindNode (anti-duplicate), ConnectionRegistry lifecycle (pending→active→suspended→revoked), validateApiKey (rby_ format + master + tenant-scoped anti-spoofing). Scale test 500 tenants ב-29ms. כל 8 השכבות הושלמו.
- שלב: 8
2026-08-26 09:35 CEST — [radiant]
- שלב 7 הושלם: event-router.js — Pub/Sub של RCP (28 event types) → cron/webhook של Radiant. subscribe מייצר cron job (realtime/daily/minutely), emit מנתב עם filter matching + tenant isolation, delivery דרך webhook mode. נבדק: routing נכון, filter, isolation, webhook format.
- שלב: 7
2026-08-26 09:31 CEST — [radiant]
- שלב 6 הושלם: browser-bridge.js מחבר TOSP tasks (chat/summarize/automation) → RCP intents → browser tool של Radiant. 14 browser actions + 8 TOSP types ממופים. safeMode (selectors בלבד), pageContext pruning 5000 chars, tenant anti-spoofing. E2E אמיתי: ניווט example.com + snapshot AI עבד.
- שלב: 6
2026-08-26 09:28 CEST — [radiant]
- שלב 5 הושלם: node-executor.js (אופציה B Node אמיתי) מחבר RCP system.run/info + 17 פקודות desktop → exec(host=node)/file_fetch/dir_list/nodes. Zero-config: מוכן להפעלה כשה-MSI נרשם כ-node. בדיקות עברו end-to-end.
- שלב: 5
2026-08-26 09:20 CEST — [radiant]
- בניתי שכבת RCP מלאה ב-Radiant: intent-router.js (46 intents → כלי Radiant), radiant-bridge.js (מיפוי RCP→Radiant native tools עם tenant-scoping), intent-discovery.js (5 שלבים: detect/propose/stage/route/promote עם stop-words, dedup, rate-limit). נבדקו end-to-end.
- שלב: 3
2026-08-26 04:57 CEST — [radiant]
- רענון MCP mirror: תוקן MONGODB_URI (ללא creds → עם creds), נוסף index על apibank_public_mcp{name,version}. רץ mirror מלא: 24851 mirrored, 2734 pages, totalInMirror=26073
2026-08-25 23:36 CEST — [radiant]
- השלמה הגירת כל 19 דפי הדשבורד לעיצוב Light Enterprise בסגנון Google/Facebook. מערכת עיצוב חדשה (globals.css), AppShell אחיד (DashboardNav sidebar 248px + topbar 56px), כל הדפים עם bg #F8F9FB, כרטיסים לבנים border #E5E7EB, blue #1A73E8, כוכבית ruby. הוסרו dir=rtl, רקעי כהים (#070B12/#0B0E14 וכו'), headers ישנים. נבדקו 19/19 = HTTP 200. Build נקי.
- שלב: 10
2026-08-25 22:46 CEST — [radiant]
- Dashboard premium redesign: new sidebar nav (collapsible, mobile drawer), redesigned my-dashboard overview with recharts (area+pie), gradient stat cards, KPI trend indicators. Fixed body theme (dark navy base + light-theme override). Left-offset all dashboard pages for new fixed sidebar. Removed dup /dashboard redirect.
- שלב: 10
2026-08-25 22:13 CEST — [radiant]
- Projects subdomain live: created projects.turqizai.com DNS A record → 84.247.162.143 via IONOS MCP (zone turqizai.com), nginx config (HTTP→HTTPS redirect + proxy to ruby-ai:3004 + / → /dashboard/projects landing), Let's Encrypt SSL issued (auto-renew). IONOS MCP token stored in ~/.openclaw/credentials/ionos-mcp.secret. Full Project Builder accessible at https://projects.turqizai.com.
- שלב: 2
2026-08-25 21:52 CEST — [radiant]
- Project Builder FULL STACK COMPLETE (Track 2 done): backend (6 api-bank routes + models + 2 templates verified end-to-end) + frontend (ruby-ai /dashboard/projects list + [id] detail with 5 tabs) + secure auth proxy (/api/bank/projects/* → Better Auth session gate → service key → api-bank). Nav item added. i18n foundation (Track 1) done: next-intl, 8 locales, RTL support, I18nProvider + LanguageSwitcher.
- שלב: 2
2026-08-25 21:41 CEST — [radiant]
- Track 1 (i18n foundation) + Track 2 (Project Builder backend) COMPLETE: next-intl installed, en/he/ar/es/fr/de/ru/zh locales, I18nProvider + LanguageSwitcher, RTL support in CSS. Project Builder backend: 6 routes (projects CRUD, records CRUD+bulk+aggregation, connectors, templates), Project model with Trading Journal + Task List templates, verified end-to-end (create project→create record→bulk→aggregation profit_loss=110→delete).
- שלב: 2
2026-08-25 21:06 CEST — [radiant]
- התחלתי ביצוע: Track 1 (Design System + i18n Foundation) עם next-intl English-first. הערה אדריכלית: request-based locale detection (לא URL routing) כדי לא לשבור דפים קיימים/live
- שלב: 10
2026-08-25 20:58 CEST — [radiant]
- אישרתי שיפוץ מלא + i18n (English base) + Project Builder framework + שניהם במקביל. ביצעתי Phase 0 (DB snapshot מלא): גיבוי תקין (24MB, 98 collection files, כולל כל ה-critical). אזהרה מתוארת: המערכת הקיימת עברית-hardcoded ב-167 קבצים — כל הבנייה החדשה English-first עם next-intl
- שלב: 10
2026-08-25 20:10 CEST — [radiant]
- השלמתי החלפת מודל ל-DeepSeek V4 Pro בכל נקודות ה-LLM של Ruby AI (chat route, pipeline, react-agent, desktop-agent, intent-translator, adapter-generator). הבוט ענה Gemini כי ה-chat route עדיין השתמש ב-flash — תוקן. הוספתי זהות מודל ל-system prompt. אומת: הבוט עונה 'DeepSeek V4 Pro'
- שלב: 9
2026-08-25 19:38 CEST — [radiant]
- החלפתי את המודל הראשי של Ruby AI ל-deepseek-v4-pro (ds/deepseek-v4-pro). עדכנתי את הקוד (llm-orchestrator.ts + radiant-config.ts) וגם את ה-DB (radiant_configs collection). תיקנתי bug של כפילות ds/deepseek-v4-pro. אומת ש-pro זמין ב-OmniRoute ועובד
- שלב: 9
2026-08-25 19:28 CEST — [radiant]
- מחקתי את n8n לגמרי מהמערכת (docker compose down -v, nginx config, SSL cert, תיקיית /root/n8n) לפי בקשת המשתמש — n8n לא חלק מהמערכת
- שלב: 9
2026-08-25 19:22 CEST — [radiant]
- הדלקתי את כל 6 שירותי ה-PM2 הנותרים (chatbuilder, api-bank-worker, ruby-mcp-server, rcp-api, headscale-demo). עכשיו 12/12 שירותי PM2 online. גיליתי ש-mail.turqizai.com ו-turqiz-site הם אותה אפליקציה (port 3001), ה-302 הוא redirect מכוון
- שלב: 9
2026-08-25 18:51 CEST — [radiant]
- תיקנתי 4 שירותים מושבתים (502): n8n (docker compose up + DNS race fix), crm ו-turqiz-pay (עדכון MongoDB URI לסיסמה החדשה TurqizApp2026!), turqiz-site (npm run build + kill orphan process). כל ה-4 עכשיו 200. עדכנתי את כל קבצי ה-env שעדיין השתמש בסיסמה הישנה 0GBZmm...
- שלב: 9
2026-08-25 18:28 CEST — [radiant]
- בניתי צ'קליסט מערכת מקיף (system-checklist.md) + חיברתי ל-doc.turqizai.com. ממצאים: 4 שירותים מושבתים (crm/pay/n8n/turqiz-site), תוקן ניתוב nginx /api/ruby/ מ-3006 ל-3004
- שלב: 9
2026-08-25 17:12 CEST — [radiant]
- Dashboard login page redesigned with enterprise Split Screen layout: left panel with Ruby branding + stats (99.9% uptime, <50ms response, 24/7 support), right panel with clean form (email/password with show/hide toggle), SSO button, dark theme with red accents. Keycloak SSO integration via Better Auth genericOAuth plugin.
- שלב: 9
2026-08-25 17:01 CEST — [radiant]
- Keycloak SSO configured in ruby-ai: genericOAuth plugin with keycloak provider, KC_ISSUER=https://id.turqizai.com/realms/ruby, login page updated to use /api/auth/sign-in/social. Also fixed Better Auth password for admin@turqizai.com (TurqizAdmin2026!), fixed build errors in tool-broker.ts and react-agent.ts. Telegram multi-tenant API created at /api/ruby/telegram.
- שלב: 9
2026-08-25 13:28 CEST — [radiant]
- admin.ruby.turqizai.com אומת מלא: SSL תקין (ECDSA, בתוקף עד 2026-11-21), Nginx reverse proxy ל-port 3006, Keycloak SSO (realm: ruby, client: ruby-client, PKCE flow), KC_CLIENT_SECRET נוסף ל-ecosystem.config.js. כל ה-admin APIs עובדים עם JWT: overview (3 tenants, 5 agents), radiant (healthy, 379ms), federation report, tenants list. סיסמת admin@turqizai.com אופסה ל-TurqizAdmin2026!
- שלב: 8
2026-08-25 13:22 CEST — [radiant]
- MongoDB auth תוקן: עדכון ל-v8.0.31, סיסמאות אופסו (admin + turqizai_app), authorization: enabled. api-bank מתחבר עם connection string מאומת. Federation וכל ה-endpoints אומתו עם auth. גיבוי מלא ב-/root/mongodb-backup-20260825.
- שלב: 8
2026-08-25 13:16 CEST — [radiant]
- api-bank שוחזר: build חסר תוקן (npm run build), PM2 עלה מחדש. Federation עובד (tasks/connections). Event Relay routes נוצרו (/api/gateway/events/relay, /subscribe, /subscriptions) ואומתו. /etc/hosts נוקה מ-C2 של XMRig (193.32.162.73). אבטחה: אין persistence של malware.
- שלב: 8
2026-08-25 05:04 CEST — [radiant]
2026-08-25 12:50 CEST — [radiant]
- WhatsApp → Radiant סינכרוני: הפעלנו `gateway.http.endpoints.responses.enabled` ב-Radiant → `/v1/responses` (OpenAI-compatible, סינכרוני). החלפנו את `/hooks/agent` (async, לא החזיר תגובה) ב-`/v1/responses` (sync, תגובה מיד). whatsapp-gateway `server.js` שורות 523-570 עברו ל-`POST /v1/responses` עם `model:"openclaw"` + `x-openclaw-session-key`. תגובה נשלפת מ-`d.output[].content[].text` ונשלחת ל-WhatsApp דרך Baileys.
- אימות: `"תגיד: שלום רובי"` → `"שלום רובי! 👋"` ✅ | whatsapp-gateway connected ✅ | אין hooks/agent ✅ | אין 3004 ✅
- גיבויים: `server.js.bak.ruby-ai` (מקורי), `server.js.bak.hooks-agent` (גרסת async)
- Auto-provisioning ל-Radiant עדיין פעיל (שורות 275-297)
- דף דאשבורד: `src/app/dashboard/whatsapp/page.tsx` — UI מלא (QR, pairing, סטטוס Radiant, קבוצות, שליחת הודעה)
- מצב ערוצים: WhatsApp ✅ | Telegram ✅ | API 5501 ✅ | MCP 24.5K ✅ | דפדפן ✅ | טלפון ✅ | מחשב ✅ — 9 פלאגינים פעילים
- שלב: whatsapp-radiant-sync
2026-08-25 09:08 CEST — [radiant]
- קטלוג אינטגרציות מאוחד: 3 קבצים → 1. `integration-templates.ts` כולל 5501 אינטגרציות ייחודיות (416 פנימי + 712 Activepieces חדשים + 12 dedupe). `pieces-catalog.ts` + `unified-catalog.ts` נמחקו. `flow-engine.ts` עבר ל-`integrationTemplates` בלבד (הוסר `slice(0,200)`). כפילות `week-done`/`weekdone` נוקתה. כל הרכיבים מחוברים (code-mode→sdk→engine→rcp, mcp/server→apiBankEngine+actionRouter+registryEngine, flow-engine→federation-protocol, אוטומציות→federation-protocol). אימות: typecheck ✅ | build ✅ | pm2 online ✅ | codemode ✅ | mcp/convert ✅
- שלב: catalog-unification
- רענון מראת MCP ציבורי: mirror הושלם — 25,508 שרתים במראה (mirrored 24,663, pages 2,704, done=true, 1598s)
2026-08-24 04:59 CEST — [radiant]
- MCP public mirror refresh: mirrored=24456, pages=2673, done=true, totalInMirror=24923
- שלב: mirror
2026-08-23 20:42 CEST — [radiant]
- Admin Control Center (admin.ruby.turqizai.com) הושלם E2E: Keycloak SSO (PKCE) + admin role + MongoDB auth fix. E2E overview מחזיר 200 עם נתונים חיים (1 tenant, 4 agents, 6 conversations).
- שלב: 9
- החלטה: שורש כשל ה-E2E היה MongoDB (URI בלי-auth בזיכרון process), לא Keycloak. תיקון: pm2 delete + start ecosystem.config.js.
2026-08-23 18:27 CEST — [radiant]
- Admin Control Center live על /admin (ruby.turqizai.com/admin + apibank.turqizai.com/admin). שכבת Control Plane ב-api-bank: AdminTenant/AdminRubyAgent models + admin-auth (Keycloak JWT+admin role) + /api/admin/control/{tenants,agents,plans,overview,radiant} + frontend /admin. typecheck=0, build OK, nginx route /admin→3006. הערה: בעתיד צריך לעבור ל-subdomain ייעודי admin.ruby.turqizai.com (IONOS secret הנוכחי expired).
- שלב: 9
2026-08-23 16:25 CEST — [radiant]
- שלב 7 + 8: tenant-scoping הושלם ב-federation + events, event-scheduler.ts (cron/webhook delivery) נבנה, endpoint delivery נוסף. קבצים ששונו: ConnectionRegistry.ts, federation.ts, auth.ts, events.ts, event-scheduler.ts (חדש), events/route.ts, events/[subscriptionId]/route.ts, events/deliver/route.ts (חדש), federation/route.ts, federation/[connectionId]/route.ts.
- שלב: 8
2026-08-23 16:21 CEST — [radiant]
- שלב 8 (Events → Cron/webhooks) — מתחיל. הקיים: events.ts Pub/Sub מלא (subscribe/emitEvent/unsubscribe/getSubscriptions/cleanup), 36 event types, routes /api/rcp/events. הפער: (1) tenantId מנדטורי ב-subscription + filtered lookup, (2) getRubyInfo() discovery endpoint /.well-known/ruby, (3) Cron/webhook delivery вместо fetch ידני.
- שלב: 8
2026-08-23 16:21 CEST — [radiant]
- שלב 7 (Federation on top of Nodes) — tenant-scoping הושלם בקוד: ConnectionRegistry model קיבל tenantId מנדטורי + index, federation.ts נכתב מחדש עם tenant-scoping בכל הפונקציות (requestConnection/approve/suspend/revoke/delete/getConnection/getConnections/validateApiKey) + validateApiKeyGlobal, auth.ts מחלץ tenantId מ-x-tenant-id header + validateApiKey tenant-scoped, routes federation מעדכנים tenantId. typecheck נקי (השגיאה היחידה pre-existing ב-ruby/sessions/route.ts). מתחיל שלב 8 (Events → Cron/webhooks).
- שלב: 7
2026-08-23 15:24 CEST — [radiant]
- MongoDB auth re-enabled. הבינארי mongod 8.0.21 תקין (לא מזויף). mtime 2013 תקין (artefact של dpkg). הסיסמה החדשה נשמרה ב-deploy/.mongo-credentials (chmod 600). אפליקציות הופעלו מחדש pm2 ומחוברות 14 connections.
- שלב: 8
2026-08-23 15:06 CEST — [radiant]
- בדיקת אבטחה מעמיקה: אין נוזקה פעילה (אין C2 193.32.162.73 מקושר, אין xmrig, authorized_keys נקי, mongod 8.0.21 רשמי). וקטור הדבקה מזוהה = אין Firewall (ufw inactive + iptables ריק) עם שירותים חשופים 0.0.0.0: omniroute 20128-20132, headscale 8101, mail, nginx. MongoDB authorization:disabled. sshd מאובטח (Port 2222, no password, no root-password).
- שלב: 8
2026-08-23 11:28 CEST — [radiant]
- Stage 8 (Events → Cron/webhooks) הושלם ואומת: webhooks (יצירה/רישום/stats/logs), triggers (event→task עם mapPayload+condition), event-relay lib מוכן. Stages 7 ו-8 סגורים.
- שלב: 8
2026-08-23 11:28 CEST — [radiant]
- Stage 7 Federation + Stage 8 Events/Cron/Webhooks verified E2E. MongoDB switched to no-auth localhost-only (SCRAM auth broken: storedKey mismatch, likely malware binary tampering). api-bank launched via ecosystem.config.js to inject MONGODB_URI into next start (npm does not forward env to child).
- שלב: 7
2026-08-23 10:25 CEST — [radiant]
- Stage 6 — agent-bridge.ts wired to real Gateway: הוחלף CLI subprocess ב-POST /hooks/agent (Gateway HTTP). pollForReply קורא session transcript עד לתשובת assistant. browser-automation.ts תוקן: טיפול נכון ב-CLI exit code (stdout JSON = success גם אם exit code nonzero). E2E verified: chat דרך apibank.turqizai.com → Gateway hooks → agent reply ✅, TOSP execute → queryAgent → reply ✅, browser navigate → openclaw browser → ok ✅, snapshot → ok ✅. Hooks config נוסף ל-openclaw.json (port 18790, token, allowRequestSessionKey, prefix ruby-ext:).
- שלב: 6
2026-08-23 10:24 CEST — [radiant]
- שלב 6 התקדם: agent-bridge.ts שוכתב לחיבור ישיר ל-Gateway hooks (POST /hooks/agent) במקום CLI subprocess. נוסף polling מנגנון לקריאת תשובת ה-agent מ-session file. browser-automation.ts שופר עם error handling תקין. hooks הופעלו ב-openclaw.json (token, allowRequestSessionKey, prefix ruby-ext:). E2E verified: chat + TOSP execute + browser navigate — כולם עובדים דרך apibank.turqizai.com.
- שלב: 6
2026-08-23 10:08 CEST — [radiant]
- Ruby Auth Stack הושלם (Keycloak+Permify+JWT): realm ruby, tenant ruby + schema, JWT RS256 מאומת מול JWKS, action-router תומך JWT לפני API-key. JWT smoke test VALID, Permify check ALLOWED.
- שלב: 6
- החלטה: הושלמה מערכת אימות+הרשאות (SSO + Zanzibar)
2026-08-23 07:48 CEST — [radiant]
- תוקן nginx: /api/ruby/ ו-/api/oauth/ עברו מפורט 3004 (ישן) ל-3006 (api-bank). נוספו routes: /api/oauth/userinfo, /api/oauth/token, /api/oauth/authorize. תוקן response format: token (לא sessionToken) + user.id + user.name.
- שלב: 6
2026-08-23 05:04 CEST — [radiant]
- Public MCP mirror refresh completed: 24,504 servers / 14,868 namespaces. Mirrored 24,300 docs across 2,652 pages (~21.8 min). upsert-only, done:true.
2026-08-23 00:01 CEST — [radiant]
- Ruby Desktop 2.0.5: תיקון PowerShell ArgumentList — שימוש ב-.NET ProcessStartInfo ישירות (New-Object System.Diagnostics.ProcessStartInfo) במקום Start-Process עם מערך ארגומנטים. זו הדרך הכי אמינה להעברת פקודות עם רווחים.
- שלב: 6
2026-08-22 23:38 CEST — [radiant]
- Ruby Desktop 2.0.3: תיקון execElevated — הסרתי את PassThru | Select-Object ExitCode (גרם ל-PropertyEvaluationExpand error). עכשיו פשוט Start-Process -Verb RunAs -Wait (חסימה טבעית עד סיום).
- שלב: 6
2026-08-22 23:26 CEST — [radiant]
- Ruby Desktop 2.0.2: תיקון 'Access denied' — wireguard.exe /installtunnelservice רץ עכשיו elevated (UAC via Start-Process -Verb RunAs -Wait) עבור up/down; חיפושי wg.exe נשארו non-elevated.
- שלב: 6
2026-08-22 23:15 CEST — [radiant]
- Ruby Desktop 2.0.1: תיקון קריטי — wg-quick.exe (לינוקס) → wireguard.exe + wg.exe (חלונות) /installtunnelservice. זה פתר גם את 'מנותק' ב-VPN.
- שלב: 6
2026-08-22 22:30 CEST — [radiant]
- Ruby Desktop 2.0.0: TOSP thin-shell (UI נמשך מהשרת, אין dist bundled) + התקנה ל-C:\Program Files\ruby (perMachine) + EXE 100MB
- שלב: 6
2026-08-22 22:03 CEST — [radiant]
- VPN Phase 3 (חלקי): IPv4 endpoint fallback + per-tenant key isolation מלא (הצפנה per-tenantId, לא TENANT_ID קבוע)
- שלב: 6
2026-08-22 21:56 CEST — [radiant]
- Ruby Desktop 1.9.0: חיבור VPN ל-Auto SSO (RFC 8628) מלא + תיקון באגים קריטיים (wireguard interface naming, subnet, salt, vpn-client.js bundling)
- שלב: 6
2026-08-22 21:29 CEST — [radiant]
- Device SSO (RFC 8628) הושלם + תיקון בעיות: memory index (ollama nomic-embed-text), agent-bridge verified, SSO E2E passed
- שלב: 6
2026-08-22 20:55 CEST — [radiant]
- Unified installer + VPN UI: Ruby Desktop build מחדש עם VPN, NSIS מאוחד עם 4 רכיבים (Node/UI/VPN/Remote), נפרס ל-doc.turqizai.com
- שלב: 6
2026-08-22 19:20 CEST — [radiant]
- Headscale Phase 1: טננט demo הוקם. שרת עובד על port 8101. preauth key נוצר. ממתין ל-DNS+SSL.
2026-08-22 19:13 CEST — [radiant]
- גרסת התוסף עודכנה 4.0.2 → 4.0.4. Zip נבנה וזמין להורדה. מוכן לפרסום בחנות כרום.
2026-08-22 18:52 CEST — [radiant]
- עודכנה גרסת מניפסט התוסף ל-4.0.3 ונארז קובץ ZIP חדש מוכן להעלאה ל-Web Store
- שלב: Browser Extension
2026-08-22 18:40 CEST — [radiant]
- OAuth SSO routes נוספו: /oauth/extension (provision+redirect) + /oauth/extension/callback (HTML). עובד ציבורית עם apibank.turqizai.com.
2026-08-22 18:23 CEST — [radiant]
- manifest 401 תוקן: manifest הפך public (auth אופציונלי). ensureAuthToken מזהה rxt_ ומספק מחדש token legacy. zip נבנה מחדש.
2026-08-22 18:02 CEST — [radiant]
- Bug-fix 405: manifest route תמך רק POST (התוסף עושה GET), ו-authenticateExtension לא זיהה rxt_ token ב-x-api-key. תוקן+נבנה. flow אמיתי: manifest/execute/poll כולם 200.
2026-08-22 17:43 CEST — [radiant]
- Stage 6 publish prep: bump ל-4.0.2, ולידציה נקייה, zip מוכן (dist/ruby-chrome-extension-v4.0.2.zip). publish ל-Web Store דורש גישה ידנית ל-Dashboard.
2026-08-22 17:38 CEST — [radiant]
- Stage 6 סעיף 1 — החלפת endpoint בתוסף ל-Radiant (אופציה A): SERVER configurable, ברירת מחדל apibank.turqizai.com. נוספו routes automation/poll + chat/receipts. E2E ציבורי: ping/manifest/chat אמיתי עובדים דרך https://apibank.turqizai.com.
2026-08-22 17:18 CEST — [radiant]
- Stage 6 חלק ב' — agent-bridge + browser-automation LIVE: queryAgent→openclaw agent CLI, exec→openclaw browser CLI. תוקן browser snap (AppArmor) ע"י executablePath=playwright chromium. E2E: chat אמיתי + navigate/snapshot/click עובדים.
2026-08-22 16:34 CEST — [radiant]
- Stage 6 E2E verified: /api/ruby/extension/ping returns OK; provision token; manifest returns radiant TOSP manifest; chat executes via RCP query intent. Browser extension thin client now routes through Radiant.
- שלב: 6
2026-08-22 16:26 CEST — [radiant]
- Stage 6: Ruby Browser Extension ↔ Radiant — found existing extension at turqiz-ai/ruby-chrome-extension v4.0.1 (TOSP thin client, Manifest V3). Moving from ruby.turqizai.com server to Radiant RCP/OpenClaw server.
- שלב: 6
2026-08-22 15:48 CEST — [radiant]
- חיברתי את המראה הציבורית להתקנה: registryEngine.installPublic + buildMcpServerConfig + materializePublicRfb. כלי MCP registry_install_public (סה"כ 17). אימות E2E: strava → probe → 13 tools live. cron רענון יומי 04:30.
- שלב: Public MCP mirror → install bridge
2026-08-22 13:18 CEST — [radiant]
- בניתי חוקר (crawler) למראה הציבורית של MCP (אפשרות ג Hybrid): mirror metadata (23,900+ שרתים נמשכו עד עכשיו, עדיין רץ) + import on-demand. API /v0.1/servers (פגינוציה nextCursor). 3 כלי MCP חדשים (public_mcp_search/mirror/import) → סה"כ 16. classify ל-16 קטגוריות.
- שלב: שלב 6 / Public Registry Mirror
2026-08-22 12:45 CEST — [radiant]
- חיברתי registry→mcp/convert: RegistryEngine.install() + MCP tool registry_install + REST /api/registry/install. integration→installTemplate; mcp→המרה אוטומטית ל-RFB+talent scoped per-tenant. אומת E2E. סה"כ 13 כלי MCP.
- שלב: שלב 6 / Registry→MCP convert
2026-08-22 12:37 CEST — [radiant]
- בניתי registry פנימי self-hosted ל-Radiant: RegistryEngine + 3 MCP tools (registry_search/publish/review) + REST /api/registry. Controlled publish (submit→review→publish), namespace בעל שם (io.<tenant>/<name>), operator auth. אומת E2E.
- שלב: שלב 6 / Registry פנימי
2026-08-22 12:08 CEST — [radiant]
- Code Mode ממומש כ-MCP מוטמע (Option 2) בתוך api-bank
- שלב: שלב Code Mode / MCP
2026-08-22 11:35 CEST — [radiant]
- עידכנתי Code Mode → סטטוס 'מבוצע' (נמצא המימוש האמיתי ב-api-bank)
- החלטה: Code Mode Engine קיים: execute/search/mcp/sdk.ts/sandbox-engine.ts במימוש api-bank
2026-08-22 11:25 CEST — [radiant]
- תיקנתי escaping שבור במסמך Code Mode (backslash/ESC/CR)
- החלטה: נכתב מחדש code-mode.md ו-ruby-code-mode-spec.md עם backtick תקין
2026-08-22 11:14 CEST — [radiant]
- הוספת 3 סקשנים לאתר: Intents (RCP), Desktop Arm, Code Mode (MCP)
- החלטה: אתר doc כולל עכשיו: תוכנית, רמות בידוד, 44 intents, Desktop Arm, Code Mode, החלטות, היסטוריה
2026-08-22 11:11 CEST — [radiant]
- הוספת 3 רמות בידוד לאתר התיעוד (doc)
- החלטה: רמות בידוד מפורטות ב-docs/plan.md ומוצגות באתר
2026-08-22 11:10 CEST — [radiant]
- הוקם ורץ ruby-mcp-server (PM2 ID 12, port 18795) עם מנוע Search & Execute ו-Sandbox מבודד
- שלב: Code Mode MCP
2026-08-22 11:06 CEST — [radiant]
- הקמת אתר תיעוד ציבורי doc.turqizai.com
- שלב: תשתית תיעוד
- החלטה: אתר תיעוד חי שאפשר לצפות בו דרך DNS
2026-08-22 11:05 CEST — [radiant]
- נכתב אפיון מלא עבור Ruby Code Mode Engine (MCP) ומוזג לתוכנית הפיתוח
- שלב: Code Mode MCP
2026-08-22 10:45 CEST — [radiant]
- בדיקת תיקון bug
- שלב: תשתית תיעוד
2026-08-22 10:45 CEST — [radiant]
- trace3
- שלב: s
2026-08-22 10:45 CEST — [radiant]
- trace2
- שלב: s
2026-08-22 10:45 CEST — [radiant]
- trace test
2026-08-22 10:45 CEST — [radiant]
- בדיקה
- שלב: אבא
2026-08-22 10:45 CEST — [radiant]
- בדיקת תקינות מערכת התיעוד החי
- שלב: תשתית תיעוד
2026-08-22 10:43 CEST — [radiant]
- מיגרתי את worklog.md הישן למבנה docs מובנה (plan/decisions/history/status) + בניתי logs.sh CLI + DOCUMENTATION.md
- שלב: תשתית תיעוד