aiden-runtime 3.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +661 -0
- package/README.md +465 -0
- package/config/devos.config.json +186 -0
- package/config/hardware.json +9 -0
- package/config/model-selection.json +7 -0
- package/config/setup-complete.json +20 -0
- package/dist/api/routes/computerUse.js +112 -0
- package/dist/api/server.js +6870 -0
- package/dist/bin/npx-init.js +71 -0
- package/dist/coordination/commandGate.js +115 -0
- package/dist/coordination/livePulse.js +127 -0
- package/dist/core/agentLoop.js +2718 -0
- package/dist/core/agentShield.js +231 -0
- package/dist/core/aidenIdentity.js +215 -0
- package/dist/core/aidenPersonality.js +166 -0
- package/dist/core/aidenSdk.js +374 -0
- package/dist/core/asyncTasks.js +82 -0
- package/dist/core/auditTrail.js +61 -0
- package/dist/core/auxiliaryClient.js +114 -0
- package/dist/core/bgLLM.js +108 -0
- package/dist/core/bm25.js +68 -0
- package/dist/core/callbackSystem.js +64 -0
- package/dist/core/channels/adapter.js +6 -0
- package/dist/core/channels/discord.js +173 -0
- package/dist/core/channels/email.js +253 -0
- package/dist/core/channels/imessage.js +164 -0
- package/dist/core/channels/manager.js +96 -0
- package/dist/core/channels/signal.js +140 -0
- package/dist/core/channels/slack.js +139 -0
- package/dist/core/channels/twilio.js +144 -0
- package/dist/core/channels/webhook.js +186 -0
- package/dist/core/channels/whatsapp.js +185 -0
- package/dist/core/clarifyBus.js +75 -0
- package/dist/core/codeInterpreter.js +82 -0
- package/dist/core/computerControl.js +439 -0
- package/dist/core/conversationMemory.js +334 -0
- package/dist/core/costTracker.js +221 -0
- package/dist/core/cronManager.js +217 -0
- package/dist/core/deepKB.js +77 -0
- package/dist/core/doctor.js +279 -0
- package/dist/core/dreamEngine.js +334 -0
- package/dist/core/entityGraph.js +169 -0
- package/dist/core/eventBus.js +16 -0
- package/dist/core/evolutionAnalyzer.js +153 -0
- package/dist/core/executionLoop.js +309 -0
- package/dist/core/executor.js +224 -0
- package/dist/core/failureAnalyzer.js +166 -0
- package/dist/core/fastPathExpansion.js +82 -0
- package/dist/core/faultEngine.js +106 -0
- package/dist/core/featureGates.js +70 -0
- package/dist/core/fileIngestion.js +113 -0
- package/dist/core/gateway.js +97 -0
- package/dist/core/goalTracker.js +75 -0
- package/dist/core/growthEngine.js +168 -0
- package/dist/core/hardwareDetector.js +98 -0
- package/dist/core/hooks.js +45 -0
- package/dist/core/httpKeepalive.js +46 -0
- package/dist/core/hybridSearch.js +101 -0
- package/dist/core/importers.js +164 -0
- package/dist/core/instinctSystem.js +223 -0
- package/dist/core/knowledgeBase.js +351 -0
- package/dist/core/learningMemory.js +121 -0
- package/dist/core/lessonsBrowser.js +125 -0
- package/dist/core/licenseManager.js +399 -0
- package/dist/core/logBuffer.js +85 -0
- package/dist/core/machineId.js +87 -0
- package/dist/core/mcpClient.js +442 -0
- package/dist/core/memoryDistiller.js +165 -0
- package/dist/core/memoryExtractor.js +212 -0
- package/dist/core/memoryIds.js +213 -0
- package/dist/core/memoryPreamble.js +113 -0
- package/dist/core/memoryQuery.js +136 -0
- package/dist/core/memoryRecall.js +140 -0
- package/dist/core/memoryStrategy.js +201 -0
- package/dist/core/messageValidator.js +85 -0
- package/dist/core/modelDiscovery.js +108 -0
- package/dist/core/modelRouter.js +118 -0
- package/dist/core/morningBriefing.js +203 -0
- package/dist/core/multiGoalValidator.js +51 -0
- package/dist/core/parallelExecutor.js +43 -0
- package/dist/core/passiveSkillObserver.js +204 -0
- package/dist/core/paths.js +57 -0
- package/dist/core/patternDetector.js +83 -0
- package/dist/core/planResponseRepair.js +64 -0
- package/dist/core/planTool.js +111 -0
- package/dist/core/playwrightBridge.js +356 -0
- package/dist/core/pluginSystem.js +121 -0
- package/dist/core/privateMode.js +85 -0
- package/dist/core/reactLoop.js +156 -0
- package/dist/core/recipeEngine.js +166 -0
- package/dist/core/responseCache.js +128 -0
- package/dist/core/runSandbox.js +132 -0
- package/dist/core/sandboxRunner.js +200 -0
- package/dist/core/scheduler.js +543 -0
- package/dist/core/secretScanner.js +49 -0
- package/dist/core/semanticMemory.js +223 -0
- package/dist/core/sessionMemory.js +259 -0
- package/dist/core/sessionRouter.js +91 -0
- package/dist/core/sessionSearch.js +163 -0
- package/dist/core/setupWizard.js +225 -0
- package/dist/core/skillImporter.js +303 -0
- package/dist/core/skillLibrary.js +144 -0
- package/dist/core/skillLoader.js +471 -0
- package/dist/core/skillTeacher.js +352 -0
- package/dist/core/skillValidator.js +210 -0
- package/dist/core/skillWriter.js +384 -0
- package/dist/core/slashAsTool.js +226 -0
- package/dist/core/spawnManager.js +197 -0
- package/dist/core/statusVerbs.js +43 -0
- package/dist/core/swarmManager.js +109 -0
- package/dist/core/taskQueue.js +119 -0
- package/dist/core/taskRecovery.js +128 -0
- package/dist/core/taskState.js +168 -0
- package/dist/core/telegramBot.js +152 -0
- package/dist/core/todoManager.js +70 -0
- package/dist/core/toolNameRepair.js +71 -0
- package/dist/core/toolRegistry.js +2730 -0
- package/dist/core/tools/calendarTool.js +98 -0
- package/dist/core/tools/companyFilingsTool.js +98 -0
- package/dist/core/tools/gmailTool.js +87 -0
- package/dist/core/tools/marketDataTool.js +135 -0
- package/dist/core/tools/socialResearchTool.js +121 -0
- package/dist/core/truthCheck.js +57 -0
- package/dist/core/updateChecker.js +74 -0
- package/dist/core/userCognitionProfile.js +238 -0
- package/dist/core/userProfile.js +341 -0
- package/dist/core/version.js +5 -0
- package/dist/core/visionAnalyze.js +161 -0
- package/dist/core/voice/audio.js +187 -0
- package/dist/core/voice/stt.js +226 -0
- package/dist/core/voice/tts.js +310 -0
- package/dist/core/voiceInput.js +118 -0
- package/dist/core/voiceOutput.js +130 -0
- package/dist/core/webSearch.js +326 -0
- package/dist/core/workflowTracker.js +72 -0
- package/dist/core/workspaceMemory.js +54 -0
- package/dist/core/youtubeTranscript.js +224 -0
- package/dist/integrations/computerUse/apiRegistry.js +113 -0
- package/dist/integrations/computerUse/screenAgent.js +203 -0
- package/dist/integrations/computerUse/visionLoop.js +296 -0
- package/dist/memory/memoryLayers.js +143 -0
- package/dist/providers/boa.js +93 -0
- package/dist/providers/cerebras.js +70 -0
- package/dist/providers/custom.js +89 -0
- package/dist/providers/gemini.js +82 -0
- package/dist/providers/groq.js +92 -0
- package/dist/providers/index.js +149 -0
- package/dist/providers/nvidia.js +70 -0
- package/dist/providers/ollama.js +99 -0
- package/dist/providers/openrouter.js +74 -0
- package/dist/providers/router.js +497 -0
- package/dist/providers/types.js +6 -0
- package/dist/security/browserVault.js +129 -0
- package/dist/security/dataGuard.js +89 -0
- package/dist/tools/eonetTool.js +72 -0
- package/dist/types/computerUse.js +2 -0
- package/dist/types/executor.js +2 -0
- package/dist-bundle/cli.js +357859 -0
- package/package.json +256 -0
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// ============================================================
|
|
3
|
+
// DevOS — Autonomous AI Execution System
|
|
4
|
+
// Copyright (c) 2026 Shiva Deore. All rights reserved.
|
|
5
|
+
// ============================================================
|
|
6
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
7
|
+
if (k2 === undefined) k2 = k;
|
|
8
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
9
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
10
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
11
|
+
}
|
|
12
|
+
Object.defineProperty(o, k2, desc);
|
|
13
|
+
}) : (function(o, m, k, k2) {
|
|
14
|
+
if (k2 === undefined) k2 = k;
|
|
15
|
+
o[k2] = m[k];
|
|
16
|
+
}));
|
|
17
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
18
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
19
|
+
}) : function(o, v) {
|
|
20
|
+
o["default"] = v;
|
|
21
|
+
});
|
|
22
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
23
|
+
var ownKeys = function(o) {
|
|
24
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
25
|
+
var ar = [];
|
|
26
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
27
|
+
return ar;
|
|
28
|
+
};
|
|
29
|
+
return ownKeys(o);
|
|
30
|
+
};
|
|
31
|
+
return function (mod) {
|
|
32
|
+
if (mod && mod.__esModule) return mod;
|
|
33
|
+
var result = {};
|
|
34
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
35
|
+
__setModuleDefault(result, mod);
|
|
36
|
+
return result;
|
|
37
|
+
};
|
|
38
|
+
})();
|
|
39
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
40
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
41
|
+
};
|
|
42
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
43
|
+
exports.FAILURE_KEYWORDS = void 0;
|
|
44
|
+
exports.detectFailureSignal = detectFailureSignal;
|
|
45
|
+
exports.analyzeFailureTrace = analyzeFailureTrace;
|
|
46
|
+
// core/failureAnalyzer.ts — N+32 Deep GEPA failure trace analysis.
|
|
47
|
+
//
|
|
48
|
+
// Detects when a task failed (via keyword signal, consecutive tool errors,
|
|
49
|
+
// budget exhaustion, or /failed command), calls an LLM to identify the root
|
|
50
|
+
// cause, appends a lesson to workspace/LESSONS.md, and degrades the skill's
|
|
51
|
+
// confidence score so future lookups are aware of the failure history.
|
|
52
|
+
//
|
|
53
|
+
// callLLM is imported DYNAMICALLY to avoid a circular dependency:
|
|
54
|
+
// server.ts → failureAnalyzer → agentLoop → server.ts (would deadlock)
|
|
55
|
+
const fs_1 = __importDefault(require("fs"));
|
|
56
|
+
const path_1 = __importDefault(require("path"));
|
|
57
|
+
const lessonsBrowser_1 = require("./lessonsBrowser");
|
|
58
|
+
// ── Failure keyword detection ─────────────────────────────────
|
|
59
|
+
exports.FAILURE_KEYWORDS = [
|
|
60
|
+
"that's wrong", "thats wrong",
|
|
61
|
+
"no that's not", "no thats not",
|
|
62
|
+
"wrong answer",
|
|
63
|
+
"didn't work", "didnt work",
|
|
64
|
+
"failed",
|
|
65
|
+
"incorrect",
|
|
66
|
+
"you got it wrong",
|
|
67
|
+
"not what i asked",
|
|
68
|
+
"that was wrong",
|
|
69
|
+
"that's not right", "thats not right",
|
|
70
|
+
"not right",
|
|
71
|
+
"that's incorrect",
|
|
72
|
+
"you're wrong", "youre wrong",
|
|
73
|
+
"wrong result",
|
|
74
|
+
];
|
|
75
|
+
function detectFailureSignal(message) {
|
|
76
|
+
const lower = message.toLowerCase();
|
|
77
|
+
return exports.FAILURE_KEYWORDS.some(kw => lower.includes(kw));
|
|
78
|
+
}
|
|
79
|
+
// ── Main analyzer ─────────────────────────────────────────────
|
|
80
|
+
async function analyzeFailureTrace(trace) {
|
|
81
|
+
// Dynamic import — prevents circular dep agentLoop ↔ server
|
|
82
|
+
let callLLM;
|
|
83
|
+
try {
|
|
84
|
+
const mod = await Promise.resolve().then(() => __importStar(require('./agentLoop')));
|
|
85
|
+
callLLM = mod.callLLM;
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
console.warn('[failureAnalyzer] could not import callLLM — writing minimal lesson');
|
|
89
|
+
_writeMinimalLesson(trace);
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
const transcript = [
|
|
93
|
+
`User request: ${trace.userMessage}`,
|
|
94
|
+
`AI response (truncated): ${trace.aiReply.slice(0, 600)}`,
|
|
95
|
+
`Tools used: ${trace.toolsUsed.join(', ') || 'none'}`,
|
|
96
|
+
`Errors: ${trace.errors.join('; ') || 'none'}`,
|
|
97
|
+
`Failure signal: ${trace.signal}`,
|
|
98
|
+
].join('\n');
|
|
99
|
+
const prompt = `You are a failure analyzer for an AI assistant. Analyze why the following task produced a bad result.
|
|
100
|
+
|
|
101
|
+
${transcript}
|
|
102
|
+
|
|
103
|
+
Respond with ONLY valid JSON and nothing else:
|
|
104
|
+
{
|
|
105
|
+
"rootCause": "1-sentence technical root cause",
|
|
106
|
+
"pattern": "one of: wrong_tool | hallucination | scope_creep | api_error | missing_context | bad_plan | timeout | unknown",
|
|
107
|
+
"lesson": "1-2 sentence actionable rule for the AI — start with When / Always / Never / If",
|
|
108
|
+
"failedSkill": "skill folder name if a learned/approved/installed skill was the culprit, or null"
|
|
109
|
+
}`;
|
|
110
|
+
let analysis = null;
|
|
111
|
+
try {
|
|
112
|
+
// callLLM signature: (prompt, apiKey?, model?, provider?) — pass nulls to use defaults
|
|
113
|
+
const raw = await callLLM(prompt, null, null, null);
|
|
114
|
+
const text = typeof raw === 'string' ? raw : (raw?.content ?? '');
|
|
115
|
+
const json = text.match(/\{[\s\S]*\}/);
|
|
116
|
+
if (json)
|
|
117
|
+
analysis = JSON.parse(json[0]);
|
|
118
|
+
}
|
|
119
|
+
catch (e) {
|
|
120
|
+
console.warn('[failureAnalyzer] LLM analysis failed:', e.message);
|
|
121
|
+
}
|
|
122
|
+
if (!analysis) {
|
|
123
|
+
_writeMinimalLesson(trace);
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
// Write lesson to LESSONS.md
|
|
127
|
+
const lessonText = `[${analysis.pattern}] ${analysis.lesson} (rootCause: ${analysis.rootCause})`;
|
|
128
|
+
(0, lessonsBrowser_1.appendLesson)(lessonText);
|
|
129
|
+
console.log(`[failureAnalyzer] lesson appended: ${lessonText.slice(0, 80)}…`);
|
|
130
|
+
// Degrade skill confidence if a skill was identified
|
|
131
|
+
if (analysis.failedSkill) {
|
|
132
|
+
_degradeSkill(analysis.failedSkill, analysis.rootCause);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
// ── Helpers ───────────────────────────────────────────────────
|
|
136
|
+
function _writeMinimalLesson(trace) {
|
|
137
|
+
const text = `[unknown] When the user signals failure (${trace.signal}), review tool outputs carefully before responding. Tools used: ${trace.toolsUsed.join(', ') || 'none'}.`;
|
|
138
|
+
(0, lessonsBrowser_1.appendLesson)(text);
|
|
139
|
+
console.log('[failureAnalyzer] minimal lesson written (no LLM analysis)');
|
|
140
|
+
}
|
|
141
|
+
function _degradeSkill(skillName, rootCause) {
|
|
142
|
+
const cwd = process.cwd();
|
|
143
|
+
const folders = ['learned', 'approved', 'installed'];
|
|
144
|
+
for (const folder of folders) {
|
|
145
|
+
const metaPath = path_1.default.join(cwd, 'workspace', 'skills', folder, skillName, 'meta.json');
|
|
146
|
+
if (!fs_1.default.existsSync(metaPath))
|
|
147
|
+
continue;
|
|
148
|
+
try {
|
|
149
|
+
const meta = JSON.parse(fs_1.default.readFileSync(metaPath, 'utf-8'));
|
|
150
|
+
meta.failCount = (meta.failCount ?? 0) + 1;
|
|
151
|
+
meta.lastFailureReason = rootCause;
|
|
152
|
+
meta.confidence = Math.max(0.1, (meta.confidence ?? 1.0) - 0.15);
|
|
153
|
+
// Auto-deprecate after 3 consecutive failures
|
|
154
|
+
if (meta.failCount >= 3) {
|
|
155
|
+
meta.deprecated = true;
|
|
156
|
+
console.warn(`[failureAnalyzer] skill "${skillName}" auto-deprecated after ${meta.failCount} failures`);
|
|
157
|
+
}
|
|
158
|
+
fs_1.default.writeFileSync(metaPath, JSON.stringify(meta, null, 2) + '\n', 'utf-8');
|
|
159
|
+
console.log(`[failureAnalyzer] degraded skill "${skillName}" → confidence ${meta.confidence.toFixed(2)}, failCount ${meta.failCount}`);
|
|
160
|
+
}
|
|
161
|
+
catch (e) {
|
|
162
|
+
console.warn(`[failureAnalyzer] could not update meta for "${skillName}":`, e.message);
|
|
163
|
+
}
|
|
164
|
+
break; // only update the first match
|
|
165
|
+
}
|
|
166
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// ============================================================
|
|
3
|
+
// DevOS — Autonomous AI Execution System
|
|
4
|
+
// Copyright (c) 2026 Shiva Deore. All rights reserved.
|
|
5
|
+
// ============================================================
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.matchFastPath = matchFastPath;
|
|
8
|
+
// core/fastPathExpansion.ts — Phase 5 of Prompt 10.
|
|
9
|
+
//
|
|
10
|
+
// Classifies messages that can be answered directly by streamChat without
|
|
11
|
+
// going through the planner, cutting 2–8s of planner latency for ~60% of
|
|
12
|
+
// typical user messages.
|
|
13
|
+
//
|
|
14
|
+
// A message is a FAST-PATH candidate when it:
|
|
15
|
+
// - Is a direct knowledge/conversational question (no tools required)
|
|
16
|
+
// - Requests explanation, definition, translation, or opinion
|
|
17
|
+
// - Asks for short creative output (joke, quote, haiku)
|
|
18
|
+
// - Does NOT contain signals for file I/O, code execution, web search,
|
|
19
|
+
// git, screen control, or multi-step planning keywords.
|
|
20
|
+
// ── Patterns that indicate a tool-less, plannable-free response ──────────────
|
|
21
|
+
/** Positive patterns: message can likely be answered without any tools. */
|
|
22
|
+
const FAST_PATH_PATTERNS = [
|
|
23
|
+
// Knowledge / explanation
|
|
24
|
+
/^(what (is|are|was|were)|who (is|are|was|were)|where (is|are)|when (is|are|did|was)|why (is|are|do|does|did)|how (do|does|did|can|to)\b)/i,
|
|
25
|
+
// Definition
|
|
26
|
+
/^(define|explain|describe|tell me (about|what)|what does .+ mean)/i,
|
|
27
|
+
// Math / conversion
|
|
28
|
+
/^\d[\d\s+\-*/^().]*=?\s*\??\s*$|^(convert|calculate|what is \d|how (many|much) (is|are|does))/i,
|
|
29
|
+
// Translation
|
|
30
|
+
/^(translate|how do you say|what is .+ in (spanish|french|german|japanese|hindi|arabic|chinese|portuguese|italian|russian|korean))/i,
|
|
31
|
+
// Opinion / recommendation (no research needed)
|
|
32
|
+
/^(what (should|do) (i|you)|which (is better|do you prefer|would you recommend)|can you recommend)/i,
|
|
33
|
+
// Short creative
|
|
34
|
+
/^(tell me a (joke|story|fact|riddle)|give me a (quote|joke|haiku|limerick|fun fact)|write (a|me a) (poem|haiku|limerick|joke|quote|one-liner))/i,
|
|
35
|
+
// Simple yes/no questions
|
|
36
|
+
/^(is (it|that|this)|are (you|there|they)|does (it|that)|can (you|i|we)\b)/i,
|
|
37
|
+
// Casual conversational
|
|
38
|
+
/^(sounds good|makes sense|that makes sense|i see|understood|got it|noted|alright|sure|of course|no problem|nevermind|never mind|forget it|never mind that)/i,
|
|
39
|
+
];
|
|
40
|
+
/** Negative patterns: if ANY match, the message needs the planner even if a positive matched. */
|
|
41
|
+
const PLANNER_REQUIRED_PATTERNS = [
|
|
42
|
+
// File operations
|
|
43
|
+
/\b(read|write|save|create|delete|move|copy|rename|open|close|download|upload)\b.*\b(file|folder|directory|document|pdf|csv|json|txt|xlsx|zip)\b/i,
|
|
44
|
+
/\.(txt|csv|json|md|pdf|py|js|ts|sh|bat|ps1|xlsx|docx)\b/i,
|
|
45
|
+
// Code execution
|
|
46
|
+
/\b(run|execute|build|compile|deploy|install|start|launch|npm|pip|python|node|powershell|bash|terminal|shell|script)\b/i,
|
|
47
|
+
// Web / research
|
|
48
|
+
/\b(search|google|find (online|on the web)|browse|fetch|scrape|web|http|url|website|news|latest|current|today's|real.?time)\b/i,
|
|
49
|
+
// Screen / system control
|
|
50
|
+
/\b(click|type (in|into)|screenshot|screen|mouse|keyboard|open (app|browser|chrome|window)|close (app|window))\b/i,
|
|
51
|
+
// Git
|
|
52
|
+
/\b(git|commit|push|pull|branch|merge|diff|repository|repo)\b/i,
|
|
53
|
+
// Multi-step planning keywords
|
|
54
|
+
/\b(then|after that|next|first .+ then|step by step|automate|workflow|pipeline|schedule|every (day|hour|minute)|on a schedule)\b/i,
|
|
55
|
+
// Email / calendar
|
|
56
|
+
/\b(send (email|mail|message)|check (email|calendar)|schedule (meeting|call)|remind me)\b/i,
|
|
57
|
+
];
|
|
58
|
+
/**
|
|
59
|
+
* Returns true if this message can skip the planner and go directly to streamChat.
|
|
60
|
+
* False means: use the planner (may need tool calls or multi-step execution).
|
|
61
|
+
*/
|
|
62
|
+
function matchFastPath(message) {
|
|
63
|
+
const trimmed = message.trim();
|
|
64
|
+
// Very short messages are usually conversational
|
|
65
|
+
if (trimmed.length < 20 && !/\b(run|exec|create|write|search|find|git)\b/i.test(trimmed)) {
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
68
|
+
// Any planner-required signal vetoes fast-path
|
|
69
|
+
if (PLANNER_REQUIRED_PATTERNS.some(p => p.test(trimmed)))
|
|
70
|
+
return false;
|
|
71
|
+
// Check positive patterns
|
|
72
|
+
if (FAST_PATH_PATTERNS.some(p => p.test(trimmed)))
|
|
73
|
+
return true;
|
|
74
|
+
// Messages over 300 chars with no positive match go to planner
|
|
75
|
+
// (likely a detailed task description)
|
|
76
|
+
if (trimmed.length > 300)
|
|
77
|
+
return false;
|
|
78
|
+
// Medium-length messages with question marks are likely knowledge questions
|
|
79
|
+
if (trimmed.includes('?') && trimmed.length < 200)
|
|
80
|
+
return true;
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// ============================================================
|
|
3
|
+
// DevOS — Autonomous AI Execution System
|
|
4
|
+
// Copyright (c) 2026 Shiva Deore. All rights reserved.
|
|
5
|
+
// ============================================================
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.faultEngine = void 0;
|
|
8
|
+
// ── Classification rules ───────────────────────────────────────
|
|
9
|
+
const RULES = [
|
|
10
|
+
{
|
|
11
|
+
test: m => /timeout|timed out/i.test(m),
|
|
12
|
+
errorType: 'TIMEOUT',
|
|
13
|
+
retryable: true,
|
|
14
|
+
severity: 'medium',
|
|
15
|
+
repairCommand: 'retry with longer timeoutMs',
|
|
16
|
+
manualFix: 'Increase timeoutMs in action options or check network latency.',
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
test: m => /ECONNREFUSED|ENOTFOUND|network|fetch/i.test(m),
|
|
20
|
+
errorType: 'NETWORK',
|
|
21
|
+
retryable: true,
|
|
22
|
+
severity: 'medium',
|
|
23
|
+
repairCommand: 'check network connectivity',
|
|
24
|
+
manualFix: 'Verify the target host is reachable. Check DEVOS_API_URL env var.',
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
test: m => /401|403|unauthorized|forbidden|auth/i.test(m),
|
|
28
|
+
errorType: 'AUTH',
|
|
29
|
+
retryable: false,
|
|
30
|
+
severity: 'high',
|
|
31
|
+
repairCommand: 'refresh credentials',
|
|
32
|
+
manualFix: 'API key or token may be expired. Refresh in config/api-keys.json.',
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
test: m => /404|not found|no such/i.test(m),
|
|
36
|
+
errorType: 'NOT_FOUND',
|
|
37
|
+
retryable: false,
|
|
38
|
+
severity: 'medium',
|
|
39
|
+
repairCommand: 'verify resource path',
|
|
40
|
+
manualFix: 'The resource was not found. Check the endpoint or file path.',
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
test: m => /permission|access denied|EACCES/i.test(m),
|
|
44
|
+
errorType: 'PERMISSION',
|
|
45
|
+
retryable: false,
|
|
46
|
+
severity: 'high',
|
|
47
|
+
repairCommand: 'check file/API permissions',
|
|
48
|
+
manualFix: 'Permission denied. Check file ownership or API scope.',
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
test: m => /selector|element|click|visible change|no visible/i.test(m),
|
|
52
|
+
errorType: 'SCREEN_CHANGE',
|
|
53
|
+
retryable: true,
|
|
54
|
+
severity: 'medium',
|
|
55
|
+
repairCommand: 'retry action with longer wait',
|
|
56
|
+
manualFix: 'Screen element not found or did not change. The UI may have changed.',
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
test: m => /docker|container|vault/i.test(m),
|
|
60
|
+
errorType: 'DOCKER',
|
|
61
|
+
retryable: true,
|
|
62
|
+
severity: 'high',
|
|
63
|
+
repairCommand: 'docker info && docker ps',
|
|
64
|
+
manualFix: 'Docker daemon may not be running. Run: docker info',
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
test: m => /ollama|llm|model|llava/i.test(m),
|
|
68
|
+
errorType: 'LLM',
|
|
69
|
+
retryable: true,
|
|
70
|
+
severity: 'medium',
|
|
71
|
+
repairCommand: 'ollama serve',
|
|
72
|
+
manualFix: 'LLM unavailable. Ensure Ollama is running: ollama serve',
|
|
73
|
+
},
|
|
74
|
+
];
|
|
75
|
+
// ── FaultEngine class ─────────────────────────────────────────
|
|
76
|
+
class FaultEngine {
|
|
77
|
+
/**
|
|
78
|
+
* Classify an error message and return repair strategies.
|
|
79
|
+
* Context is optional metadata (e.g. actionType, workspacePath).
|
|
80
|
+
* Can be called with 1 or 2 arguments.
|
|
81
|
+
*/
|
|
82
|
+
classify(message, context) {
|
|
83
|
+
const msg = message ?? '';
|
|
84
|
+
for (const rule of RULES) {
|
|
85
|
+
if (rule.test(msg)) {
|
|
86
|
+
return {
|
|
87
|
+
errorType: rule.errorType,
|
|
88
|
+
message: msg,
|
|
89
|
+
retryable: rule.retryable,
|
|
90
|
+
severity: rule.severity,
|
|
91
|
+
repairCommand: rule.repairCommand,
|
|
92
|
+
manualFix: rule.manualFix,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
return {
|
|
97
|
+
errorType: 'UNKNOWN',
|
|
98
|
+
message: msg,
|
|
99
|
+
retryable: false,
|
|
100
|
+
severity: 'medium',
|
|
101
|
+
repairCommand: undefined,
|
|
102
|
+
manualFix: 'An unexpected error occurred. Check the DevOS logs for details.',
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
exports.faultEngine = new FaultEngine();
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// ============================================================
|
|
3
|
+
// DevOS — Autonomous AI Execution System
|
|
4
|
+
// Copyright (c) 2026 Shiva Deore. All rights reserved.
|
|
5
|
+
// ============================================================
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.getFeatureLimits = getFeatureLimits;
|
|
8
|
+
exports.canUseFeature = canUseFeature;
|
|
9
|
+
exports.getLimit = getLimit;
|
|
10
|
+
exports.getTierLabel = getTierLabel;
|
|
11
|
+
// core/featureGates.ts — Free vs Pro feature limits
|
|
12
|
+
//
|
|
13
|
+
// All checks are synchronous and read from the local license cache.
|
|
14
|
+
// No network requests are made here — call verifyLicense() at startup
|
|
15
|
+
// to keep the cache fresh.
|
|
16
|
+
const licenseManager_1 = require("./licenseManager");
|
|
17
|
+
// ── Limit tables ──────────────────────────────────────────────
|
|
18
|
+
const FREE_LIMITS = {
|
|
19
|
+
maxGoals: 5,
|
|
20
|
+
maxMemories: 50,
|
|
21
|
+
maxRoutines: 10,
|
|
22
|
+
maxMachines: 1,
|
|
23
|
+
nightMode: false, // Dream Engine
|
|
24
|
+
persistentRules: false, // Standing Orders
|
|
25
|
+
watchdog: false, // Heartbeat Monitor
|
|
26
|
+
personaEngine: false, // SOUL customisation
|
|
27
|
+
exportBackup: false,
|
|
28
|
+
};
|
|
29
|
+
const PRO_LIMITS = {
|
|
30
|
+
maxGoals: Infinity,
|
|
31
|
+
maxMemories: Infinity,
|
|
32
|
+
maxRoutines: Infinity,
|
|
33
|
+
maxMachines: 2,
|
|
34
|
+
nightMode: true,
|
|
35
|
+
persistentRules: true,
|
|
36
|
+
watchdog: true,
|
|
37
|
+
personaEngine: true,
|
|
38
|
+
exportBackup: true,
|
|
39
|
+
};
|
|
40
|
+
// ── Public API ────────────────────────────────────────────────
|
|
41
|
+
/**
|
|
42
|
+
* Return the full limit table for the current tier.
|
|
43
|
+
* Reads from the local cache — instant, no I/O on most calls.
|
|
44
|
+
*/
|
|
45
|
+
function getFeatureLimits() {
|
|
46
|
+
const { isPro } = (0, licenseManager_1.getLicenseStatus)();
|
|
47
|
+
return isPro ? PRO_LIMITS : FREE_LIMITS;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Return true if the current tier allows a boolean feature.
|
|
51
|
+
* @example canUseFeature('nightMode') // false on Free
|
|
52
|
+
*/
|
|
53
|
+
function canUseFeature(feature) {
|
|
54
|
+
const limits = getFeatureLimits();
|
|
55
|
+
const val = limits[feature];
|
|
56
|
+
return typeof val === 'boolean' ? val : val > 0;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Return the numeric limit for a quota-based feature.
|
|
60
|
+
* @example getLimit('maxGoals') // 5 on Free, Infinity on Pro
|
|
61
|
+
*/
|
|
62
|
+
function getLimit(feature) {
|
|
63
|
+
return getFeatureLimits()[feature];
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Return a human-readable tier label.
|
|
67
|
+
*/
|
|
68
|
+
function getTierLabel() {
|
|
69
|
+
return (0, licenseManager_1.getLicenseStatus)().isPro ? 'Pro' : 'Free';
|
|
70
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// ============================================================
|
|
3
|
+
// DevOS — Autonomous AI Execution System
|
|
4
|
+
// Copyright (c) 2026 Shiva Deore. All rights reserved.
|
|
5
|
+
// ============================================================
|
|
6
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
7
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
8
|
+
};
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.extractPDF = extractPDF;
|
|
11
|
+
exports.extractEPUB = extractEPUB;
|
|
12
|
+
exports.extractText = extractText;
|
|
13
|
+
exports.extractFile = extractFile;
|
|
14
|
+
// core/fileIngestion.ts — Local PDF / EPUB / TXT / MD text extractor
|
|
15
|
+
//
|
|
16
|
+
// All processing is done on the user's machine. No data leaves the device.
|
|
17
|
+
//
|
|
18
|
+
// Dependencies (bundled with DevOS):
|
|
19
|
+
// pdf-parse — pure-JS PDF text extraction
|
|
20
|
+
// epub2 — EPUB chapter extraction
|
|
21
|
+
const fs_1 = __importDefault(require("fs"));
|
|
22
|
+
const path_1 = __importDefault(require("path"));
|
|
23
|
+
// ── PDF extraction ─────────────────────────────────────────
|
|
24
|
+
// Uses pdf-parse (pure JS, no native canvas dependency)
|
|
25
|
+
async function extractPDF(filePath) {
|
|
26
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
27
|
+
const pdfParse = require('pdf-parse');
|
|
28
|
+
const buf = fs_1.default.readFileSync(filePath);
|
|
29
|
+
const fileSizeMB = parseFloat((buf.length / 1024 / 1024).toFixed(2));
|
|
30
|
+
let result;
|
|
31
|
+
try {
|
|
32
|
+
result = await pdfParse(buf, { max: 0 }); // max: 0 = all pages
|
|
33
|
+
}
|
|
34
|
+
catch (e) {
|
|
35
|
+
throw new Error(`PDF parse failed: ${e.message}`);
|
|
36
|
+
}
|
|
37
|
+
const text = cleanText(result.text);
|
|
38
|
+
const wordCount = countWords(text);
|
|
39
|
+
const pageCount = result.numpages ?? 0;
|
|
40
|
+
return { text, wordCount, pageCount, format: 'pdf', fileSizeMB };
|
|
41
|
+
}
|
|
42
|
+
// ── EPUB extraction ────────────────────────────────────────
|
|
43
|
+
// Reads all spine chapters and concatenates their text content
|
|
44
|
+
async function extractEPUB(filePath) {
|
|
45
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
46
|
+
const EPub = require('epub2').EPub;
|
|
47
|
+
const fileSizeMB = parseFloat((fs_1.default.statSync(filePath).size / 1024 / 1024).toFixed(2));
|
|
48
|
+
const epub = new EPub(filePath);
|
|
49
|
+
await new Promise((resolve, reject) => {
|
|
50
|
+
epub.on('end', resolve);
|
|
51
|
+
epub.on('error', reject);
|
|
52
|
+
epub.parse();
|
|
53
|
+
});
|
|
54
|
+
const chapterIds = epub.spine.contents.map((c) => c.id);
|
|
55
|
+
const textParts = [];
|
|
56
|
+
for (const id of chapterIds) {
|
|
57
|
+
try {
|
|
58
|
+
const chapter = await new Promise((resolve, reject) => {
|
|
59
|
+
epub.getChapter(id, (err, data) => {
|
|
60
|
+
if (err)
|
|
61
|
+
reject(err);
|
|
62
|
+
else
|
|
63
|
+
resolve(data || '');
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
// Strip HTML tags from chapter HTML
|
|
67
|
+
const stripped = chapter.replace(/<[^>]+>/g, ' ');
|
|
68
|
+
textParts.push(stripped);
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
// skip unreadable chapters
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
const text = cleanText(textParts.join('\n'));
|
|
75
|
+
const wordCount = countWords(text);
|
|
76
|
+
return { text, wordCount, pageCount: 0, format: 'epub', fileSizeMB };
|
|
77
|
+
}
|
|
78
|
+
// ── Plain-text / Markdown extraction ──────────────────────
|
|
79
|
+
function extractText(filePath, format = 'txt') {
|
|
80
|
+
const raw = fs_1.default.readFileSync(filePath, 'utf-8');
|
|
81
|
+
const fileSizeMB = parseFloat((Buffer.byteLength(raw, 'utf-8') / 1024 / 1024).toFixed(2));
|
|
82
|
+
const text = cleanText(raw);
|
|
83
|
+
const wordCount = countWords(text);
|
|
84
|
+
return { text, wordCount, pageCount: 0, format, fileSizeMB };
|
|
85
|
+
}
|
|
86
|
+
// ── Router — pick extractor by extension ──────────────────
|
|
87
|
+
async function extractFile(filePath) {
|
|
88
|
+
const ext = path_1.default.extname(filePath).toLowerCase();
|
|
89
|
+
switch (ext) {
|
|
90
|
+
case '.pdf':
|
|
91
|
+
return extractPDF(filePath);
|
|
92
|
+
case '.epub':
|
|
93
|
+
return extractEPUB(filePath);
|
|
94
|
+
case '.md':
|
|
95
|
+
case '.markdown':
|
|
96
|
+
return extractText(filePath, 'md');
|
|
97
|
+
case '.txt':
|
|
98
|
+
default:
|
|
99
|
+
return extractText(filePath, 'txt');
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
// ── Helpers ────────────────────────────────────────────────
|
|
103
|
+
function cleanText(raw) {
|
|
104
|
+
return raw
|
|
105
|
+
.replace(/\r\n/g, '\n')
|
|
106
|
+
.replace(/\r/g, '\n')
|
|
107
|
+
.replace(/\n{3,}/g, '\n\n') // collapse >2 blank lines
|
|
108
|
+
.replace(/[ \t]+/g, ' ') // collapse horizontal whitespace
|
|
109
|
+
.trim();
|
|
110
|
+
}
|
|
111
|
+
function countWords(text) {
|
|
112
|
+
return text.split(/\s+/).filter(w => w.length > 0).length;
|
|
113
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// ============================================================
|
|
3
|
+
// DevOS — Autonomous AI Execution System
|
|
4
|
+
// Copyright (c) 2026 Shiva Deore. All rights reserved.
|
|
5
|
+
// ============================================================
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.gateway = void 0;
|
|
8
|
+
// core/gateway.ts — Unified channel router.
|
|
9
|
+
// All inbound messages (dashboard, Telegram, API, future channels)
|
|
10
|
+
// are routed through a single processor so they share the same
|
|
11
|
+
// memory, context, and tool pipeline.
|
|
12
|
+
const sessionRouter_1 = require("./sessionRouter");
|
|
13
|
+
// ── Gateway class ──────────────────────────────────────────────
|
|
14
|
+
class Gateway {
|
|
15
|
+
constructor() {
|
|
16
|
+
this.handlers = new Map();
|
|
17
|
+
this.messageProcessor = null;
|
|
18
|
+
this.activeChannels = new Set();
|
|
19
|
+
}
|
|
20
|
+
// ── Register the central message processor (Aiden's brain) ───
|
|
21
|
+
setProcessor(handler) {
|
|
22
|
+
this.messageProcessor = handler;
|
|
23
|
+
}
|
|
24
|
+
// ── Register a channel's outbound delivery method ─────────────
|
|
25
|
+
registerChannel(channel, deliveryHandler) {
|
|
26
|
+
this.handlers.set(channel, deliveryHandler);
|
|
27
|
+
this.activeChannels.add(channel);
|
|
28
|
+
console.log(`[Gateway] Channel registered: ${channel}`);
|
|
29
|
+
}
|
|
30
|
+
// ── Unregister a channel ──────────────────────────────────────
|
|
31
|
+
unregisterChannel(channel) {
|
|
32
|
+
this.handlers.delete(channel);
|
|
33
|
+
this.activeChannels.delete(channel);
|
|
34
|
+
console.log(`[Gateway] Channel unregistered: ${channel}`);
|
|
35
|
+
}
|
|
36
|
+
// ── Route an incoming message through Aiden ───────────────────
|
|
37
|
+
async routeMessage(message) {
|
|
38
|
+
if (!this.messageProcessor) {
|
|
39
|
+
throw new Error('No message processor registered');
|
|
40
|
+
}
|
|
41
|
+
// Resolve stable cross-channel session and attach sessionId
|
|
42
|
+
const session = sessionRouter_1.sessionRouter.getSession(message.userId, message.channel);
|
|
43
|
+
session.messageCount++;
|
|
44
|
+
message.sessionId = session.sessionId;
|
|
45
|
+
console.log(`[Gateway] ${message.channel}:${message.channelId} ` +
|
|
46
|
+
`[${session.sessionId}] → "${message.text.substring(0, 60)}"`);
|
|
47
|
+
const start = Date.now();
|
|
48
|
+
try {
|
|
49
|
+
let response = await this.messageProcessor(message);
|
|
50
|
+
const duration = Date.now() - start;
|
|
51
|
+
console.log(`[Gateway] Response ready (${duration}ms) → ${message.channel}`);
|
|
52
|
+
// Hint on Telegram first message: conversation continues on desktop
|
|
53
|
+
if (message.channel === 'telegram' && session.messageCount === 1) {
|
|
54
|
+
response += '\n\n_Tip: Continue this conversation on your desktop dashboard with full context._';
|
|
55
|
+
}
|
|
56
|
+
return response;
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
console.error(`[Gateway] Processing failed:`, error);
|
|
60
|
+
return 'Something went wrong processing your message. Try again.';
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
// ── Deliver a message to a specific channel ───────────────────
|
|
64
|
+
async deliver(message) {
|
|
65
|
+
const handler = this.handlers.get(message.channel);
|
|
66
|
+
if (!handler) {
|
|
67
|
+
console.log(`[Gateway] No handler for channel: ${message.channel}`);
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
try {
|
|
71
|
+
return await handler(message);
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
74
|
+
console.error(`[Gateway] Delivery failed to ${message.channel}:`, error);
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
// ── Broadcast to all active channels ─────────────────────────
|
|
79
|
+
async broadcast(text, exclude) {
|
|
80
|
+
for (const channel of this.activeChannels) {
|
|
81
|
+
if (channel === exclude)
|
|
82
|
+
continue;
|
|
83
|
+
await this.deliver({ channel, channelId: 'broadcast', text });
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
// ── Channel status list ────────────────────────────────────────
|
|
87
|
+
getStatus() {
|
|
88
|
+
const allChannels = [
|
|
89
|
+
'dashboard', 'telegram', 'discord', 'slack', 'whatsapp', 'signal', 'sms', 'imessage', 'email', 'api',
|
|
90
|
+
];
|
|
91
|
+
return allChannels.map(ch => ({
|
|
92
|
+
channel: ch,
|
|
93
|
+
active: this.activeChannels.has(ch),
|
|
94
|
+
}));
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
exports.gateway = new Gateway();
|