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,168 @@
|
|
|
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.taskStateManager = exports.TaskStateManager = void 0;
|
|
11
|
+
// core/taskState.ts — Persistent step-level task state.
|
|
12
|
+
// Enables crash recovery, idempotent execution, and token budgeting.
|
|
13
|
+
const fs_1 = __importDefault(require("fs"));
|
|
14
|
+
const path_1 = __importDefault(require("path"));
|
|
15
|
+
const TASKS_DIR = path_1.default.join(process.cwd(), 'workspace', 'tasks');
|
|
16
|
+
// ── TaskStateManager ───────────────────────────────────────────
|
|
17
|
+
class TaskStateManager {
|
|
18
|
+
create(taskId, goal, totalSteps, planId) {
|
|
19
|
+
const state = {
|
|
20
|
+
id: taskId,
|
|
21
|
+
goal,
|
|
22
|
+
planId,
|
|
23
|
+
status: 'running',
|
|
24
|
+
currentStep: 0,
|
|
25
|
+
totalSteps,
|
|
26
|
+
steps: [],
|
|
27
|
+
tokenUsage: 0,
|
|
28
|
+
tokenLimit: 50000,
|
|
29
|
+
createdAt: Date.now(),
|
|
30
|
+
updatedAt: Date.now(),
|
|
31
|
+
};
|
|
32
|
+
this.save(state);
|
|
33
|
+
return state;
|
|
34
|
+
}
|
|
35
|
+
load(taskId) {
|
|
36
|
+
try {
|
|
37
|
+
const statePath = path_1.default.join(TASKS_DIR, taskId, 'state.json');
|
|
38
|
+
if (!fs_1.default.existsSync(statePath))
|
|
39
|
+
return null;
|
|
40
|
+
return JSON.parse(fs_1.default.readFileSync(statePath, 'utf-8'));
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
save(state) {
|
|
47
|
+
try {
|
|
48
|
+
const taskDir = path_1.default.join(TASKS_DIR, state.id);
|
|
49
|
+
fs_1.default.mkdirSync(taskDir, { recursive: true });
|
|
50
|
+
state.updatedAt = Date.now();
|
|
51
|
+
// Atomic write — temp file then rename, avoids corruption on crash
|
|
52
|
+
const statePath = path_1.default.join(taskDir, 'state.json');
|
|
53
|
+
const tempPath = path_1.default.join(taskDir, 'state.tmp.json');
|
|
54
|
+
fs_1.default.writeFileSync(tempPath, JSON.stringify(state, null, 2));
|
|
55
|
+
fs_1.default.renameSync(tempPath, statePath);
|
|
56
|
+
}
|
|
57
|
+
catch (e) {
|
|
58
|
+
console.error(`[TaskState] Save failed for ${state.id}: ${e.message}`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
startStep(state, index, tool, input) {
|
|
62
|
+
const existing = state.steps.find(s => s.index === index);
|
|
63
|
+
if (!existing) {
|
|
64
|
+
state.steps.push({ index, tool, input, status: 'pending' });
|
|
65
|
+
}
|
|
66
|
+
state.currentStep = index;
|
|
67
|
+
this.save(state);
|
|
68
|
+
}
|
|
69
|
+
// NEVER overwrite a completed step — idempotency guard
|
|
70
|
+
completeStep(state, index, output, duration) {
|
|
71
|
+
const step = state.steps.find(s => s.index === index);
|
|
72
|
+
if (step && step.status === 'completed') {
|
|
73
|
+
console.log(`[TaskState] Step ${index} already completed — skipping overwrite`);
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
if (step) {
|
|
77
|
+
step.status = 'completed';
|
|
78
|
+
step.output = output.slice(0, 2000); // cap stored output
|
|
79
|
+
step.duration = duration;
|
|
80
|
+
step.completedAt = Date.now();
|
|
81
|
+
}
|
|
82
|
+
// Estimate token usage — chars/4 is a reasonable approximation
|
|
83
|
+
state.tokenUsage += Math.ceil(output.length / 4);
|
|
84
|
+
this.save(state);
|
|
85
|
+
}
|
|
86
|
+
failStep(state, index, error) {
|
|
87
|
+
const step = state.steps.find(s => s.index === index);
|
|
88
|
+
if (step) {
|
|
89
|
+
step.status = 'failed';
|
|
90
|
+
step.error = error;
|
|
91
|
+
step.completedAt = Date.now();
|
|
92
|
+
}
|
|
93
|
+
this.save(state);
|
|
94
|
+
}
|
|
95
|
+
complete(state) {
|
|
96
|
+
state.status = 'completed';
|
|
97
|
+
state.completedAt = Date.now();
|
|
98
|
+
this.save(state);
|
|
99
|
+
}
|
|
100
|
+
fail(state, error) {
|
|
101
|
+
state.status = 'failed';
|
|
102
|
+
state.error = error;
|
|
103
|
+
state.completedAt = Date.now();
|
|
104
|
+
this.save(state);
|
|
105
|
+
}
|
|
106
|
+
isStepCompleted(state, index) {
|
|
107
|
+
const step = state.steps.find(s => s.index === index);
|
|
108
|
+
return step?.status === 'completed';
|
|
109
|
+
}
|
|
110
|
+
isOverBudget(state) {
|
|
111
|
+
return state.tokenUsage >= state.tokenLimit;
|
|
112
|
+
}
|
|
113
|
+
// Find the first incomplete step index — used to find resume point after crash
|
|
114
|
+
getResumePoint(state) {
|
|
115
|
+
for (let i = 0; i < state.totalSteps; i++) {
|
|
116
|
+
const step = state.steps.find(s => s.index === i);
|
|
117
|
+
if (!step || step.status !== 'completed')
|
|
118
|
+
return i;
|
|
119
|
+
}
|
|
120
|
+
return state.totalSteps; // all steps done
|
|
121
|
+
}
|
|
122
|
+
getRunningTasks() {
|
|
123
|
+
const running = [];
|
|
124
|
+
try {
|
|
125
|
+
if (!fs_1.default.existsSync(TASKS_DIR))
|
|
126
|
+
return [];
|
|
127
|
+
const dirs = fs_1.default.readdirSync(TASKS_DIR).filter(d => d.startsWith('task_'));
|
|
128
|
+
for (const dir of dirs) {
|
|
129
|
+
const state = this.load(dir);
|
|
130
|
+
if (state && state.status === 'running')
|
|
131
|
+
running.push(state);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
catch { }
|
|
135
|
+
return running;
|
|
136
|
+
}
|
|
137
|
+
listAll() {
|
|
138
|
+
try {
|
|
139
|
+
if (!fs_1.default.existsSync(TASKS_DIR))
|
|
140
|
+
return [];
|
|
141
|
+
return fs_1.default.readdirSync(TASKS_DIR)
|
|
142
|
+
.filter(d => d.startsWith('task_'))
|
|
143
|
+
.sort().reverse().slice(0, 20)
|
|
144
|
+
.map(dir => {
|
|
145
|
+
const state = this.load(dir);
|
|
146
|
+
if (!state)
|
|
147
|
+
return null;
|
|
148
|
+
return {
|
|
149
|
+
id: state.id,
|
|
150
|
+
goal: state.goal.slice(0, 80),
|
|
151
|
+
status: state.status,
|
|
152
|
+
currentStep: state.currentStep,
|
|
153
|
+
totalSteps: state.totalSteps,
|
|
154
|
+
tokenUsage: state.tokenUsage,
|
|
155
|
+
tokenLimit: state.tokenLimit,
|
|
156
|
+
createdAt: state.createdAt,
|
|
157
|
+
updatedAt: state.updatedAt,
|
|
158
|
+
};
|
|
159
|
+
})
|
|
160
|
+
.filter(Boolean);
|
|
161
|
+
}
|
|
162
|
+
catch {
|
|
163
|
+
return [];
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
exports.TaskStateManager = TaskStateManager;
|
|
168
|
+
exports.taskStateManager = new TaskStateManager();
|
|
@@ -0,0 +1,152 @@
|
|
|
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.TelegramBot = void 0;
|
|
8
|
+
exports.registerTelegramCallbacks = registerTelegramCallbacks;
|
|
9
|
+
// core/telegramBot.ts — Telegram bot integration for Aiden.
|
|
10
|
+
// Uses native fetch (Node 18+). No external dependencies.
|
|
11
|
+
const callbackSystem_1 = require("./callbackSystem");
|
|
12
|
+
// ── TelegramBot ────────────────────────────────────────────────
|
|
13
|
+
class TelegramBot {
|
|
14
|
+
constructor(config) {
|
|
15
|
+
this.offset = 0;
|
|
16
|
+
this.polling = false;
|
|
17
|
+
this.token = config.botToken;
|
|
18
|
+
this.baseUrl = `https://api.telegram.org/bot${this.token}`;
|
|
19
|
+
this.allowedChats = new Set(config.allowedChatIds);
|
|
20
|
+
}
|
|
21
|
+
// ── Send a message (auto-chunks at 4000 chars) ──────────────
|
|
22
|
+
async sendMessage(chatId, text) {
|
|
23
|
+
const chunks = this.chunkMessage(text, 4000);
|
|
24
|
+
for (const chunk of chunks) {
|
|
25
|
+
try {
|
|
26
|
+
await fetch(`${this.baseUrl}/sendMessage`, {
|
|
27
|
+
method: 'POST',
|
|
28
|
+
headers: { 'Content-Type': 'application/json' },
|
|
29
|
+
body: JSON.stringify({
|
|
30
|
+
chat_id: chatId,
|
|
31
|
+
text: chunk,
|
|
32
|
+
parse_mode: 'Markdown',
|
|
33
|
+
}),
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
catch (e) {
|
|
37
|
+
console.error('[Telegram] sendMessage error:', e.message);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
// ── Show typing indicator ───────────────────────────────────
|
|
42
|
+
async sendTyping(chatId) {
|
|
43
|
+
try {
|
|
44
|
+
await fetch(`${this.baseUrl}/sendChatAction`, {
|
|
45
|
+
method: 'POST',
|
|
46
|
+
headers: { 'Content-Type': 'application/json' },
|
|
47
|
+
body: JSON.stringify({ chat_id: chatId, action: 'typing' }),
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
catch { }
|
|
51
|
+
}
|
|
52
|
+
// ── Long-poll for updates ───────────────────────────────────
|
|
53
|
+
async poll() {
|
|
54
|
+
try {
|
|
55
|
+
const response = await fetch(`${this.baseUrl}/getUpdates?offset=${this.offset}&timeout=30`);
|
|
56
|
+
const data = await response.json();
|
|
57
|
+
if (data.ok && data.result.length > 0) {
|
|
58
|
+
this.offset = data.result[data.result.length - 1].update_id + 1;
|
|
59
|
+
return data.result;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
catch (error) {
|
|
63
|
+
console.error('[Telegram] Poll error:', error.message);
|
|
64
|
+
}
|
|
65
|
+
return [];
|
|
66
|
+
}
|
|
67
|
+
// ── Main polling loop ───────────────────────────────────────
|
|
68
|
+
async startPolling(onMessage) {
|
|
69
|
+
if (this.polling)
|
|
70
|
+
return;
|
|
71
|
+
this.polling = true;
|
|
72
|
+
console.log('[Telegram] Bot started polling');
|
|
73
|
+
while (this.polling) {
|
|
74
|
+
const updates = await this.poll();
|
|
75
|
+
for (const update of updates) {
|
|
76
|
+
if (!update.message?.text)
|
|
77
|
+
continue;
|
|
78
|
+
const chatId = String(update.message.chat.id);
|
|
79
|
+
const text = update.message.text;
|
|
80
|
+
// Security: only respond to allowed chat IDs
|
|
81
|
+
// If allowedChatIds is empty, respond to everyone (first-time setup)
|
|
82
|
+
if (this.allowedChats.size > 0 && !this.allowedChats.has(chatId)) {
|
|
83
|
+
console.log(`[Telegram] Ignored message from unauthorized chat: ${chatId}`);
|
|
84
|
+
await this.sendMessage(chatId, '⚠️ Unauthorized. Add your chat ID to Aiden Settings → Channels → Telegram.');
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
console.log(`[Telegram] Message from ${chatId}: ${text.substring(0, 50)}`);
|
|
88
|
+
await this.sendTyping(chatId);
|
|
89
|
+
try {
|
|
90
|
+
const response = await onMessage(chatId, text);
|
|
91
|
+
await this.sendMessage(chatId, response);
|
|
92
|
+
}
|
|
93
|
+
catch (error) {
|
|
94
|
+
console.error('[Telegram] Error processing message:', error.message);
|
|
95
|
+
await this.sendMessage(chatId, '❌ Something went wrong processing your message. Try again.');
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
// ── Stop polling ────────────────────────────────────────────
|
|
101
|
+
stop() {
|
|
102
|
+
this.polling = false;
|
|
103
|
+
console.log('[Telegram] Bot stopped');
|
|
104
|
+
}
|
|
105
|
+
// ── Chunk long messages ─────────────────────────────────────
|
|
106
|
+
chunkMessage(text, maxLength) {
|
|
107
|
+
if (text.length <= maxLength)
|
|
108
|
+
return [text];
|
|
109
|
+
const chunks = [];
|
|
110
|
+
let remaining = text;
|
|
111
|
+
while (remaining.length > 0) {
|
|
112
|
+
if (remaining.length <= maxLength) {
|
|
113
|
+
chunks.push(remaining);
|
|
114
|
+
break;
|
|
115
|
+
}
|
|
116
|
+
// Prefer splitting at a newline
|
|
117
|
+
let splitAt = remaining.lastIndexOf('\n', maxLength);
|
|
118
|
+
if (splitAt < maxLength * 0.5) {
|
|
119
|
+
// No good newline — try a space
|
|
120
|
+
splitAt = remaining.lastIndexOf(' ', maxLength);
|
|
121
|
+
}
|
|
122
|
+
if (splitAt < maxLength * 0.5) {
|
|
123
|
+
// No good split point — hard cut
|
|
124
|
+
splitAt = maxLength;
|
|
125
|
+
}
|
|
126
|
+
chunks.push(remaining.substring(0, splitAt));
|
|
127
|
+
remaining = remaining.substring(splitAt).trim();
|
|
128
|
+
}
|
|
129
|
+
return chunks;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
exports.TelegramBot = TelegramBot;
|
|
133
|
+
// ── Callback integration ──────────────────────────────────────────────────────
|
|
134
|
+
/**
|
|
135
|
+
* Register a persistent callback subscriber that sends a typing indicator to
|
|
136
|
+
* the relevant Telegram chat whenever a tool starts executing in any session
|
|
137
|
+
* that originated from Telegram.
|
|
138
|
+
*
|
|
139
|
+
* The gateway routes Telegram messages with sessionId `telegram_telegram_{chatId}`,
|
|
140
|
+
* so we extract the chatId from that pattern and call sendTyping().
|
|
141
|
+
*
|
|
142
|
+
* @returns An unsubscribe function — call it when the bot is stopped.
|
|
143
|
+
*/
|
|
144
|
+
function registerTelegramCallbacks(bot) {
|
|
145
|
+
return callbackSystem_1.callbacks.on('tool_start', async (payload) => {
|
|
146
|
+
const prefix = 'telegram_telegram_';
|
|
147
|
+
if (payload.sessionId.startsWith(prefix)) {
|
|
148
|
+
const chatId = payload.sessionId.slice(prefix.length);
|
|
149
|
+
await bot.sendTyping(chatId);
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
}
|
|
@@ -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
|
+
//
|
|
7
|
+
// core/todoManager.ts — Per-session in-memory task list.
|
|
8
|
+
//
|
|
9
|
+
// Intentionally ephemeral: todos reset on process restart.
|
|
10
|
+
// Use aiden.todo.* or the /todo CLI command to manage items.
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.addTodo = addTodo;
|
|
13
|
+
exports.completeTodo = completeTodo;
|
|
14
|
+
exports.removeTodo = removeTodo;
|
|
15
|
+
exports.clearTodos = clearTodos;
|
|
16
|
+
exports.listTodos = listTodos;
|
|
17
|
+
exports.getTodo = getTodo;
|
|
18
|
+
exports.formatTodoList = formatTodoList;
|
|
19
|
+
let todos = [];
|
|
20
|
+
let seq = 1;
|
|
21
|
+
// ── CRUD ──────────────────────────────────────────────────────────────────────
|
|
22
|
+
function addTodo(text, priority = 'normal') {
|
|
23
|
+
const item = {
|
|
24
|
+
id: String(seq++),
|
|
25
|
+
text: text.trim(),
|
|
26
|
+
done: false,
|
|
27
|
+
priority,
|
|
28
|
+
createdAt: new Date().toISOString(),
|
|
29
|
+
};
|
|
30
|
+
todos.push(item);
|
|
31
|
+
return item;
|
|
32
|
+
}
|
|
33
|
+
function completeTodo(id) {
|
|
34
|
+
const item = todos.find(t => t.id === id);
|
|
35
|
+
if (!item)
|
|
36
|
+
return null;
|
|
37
|
+
item.done = true;
|
|
38
|
+
item.doneAt = new Date().toISOString();
|
|
39
|
+
return item;
|
|
40
|
+
}
|
|
41
|
+
function removeTodo(id) {
|
|
42
|
+
const before = todos.length;
|
|
43
|
+
todos = todos.filter(t => t.id !== id);
|
|
44
|
+
return todos.length < before;
|
|
45
|
+
}
|
|
46
|
+
function clearTodos() {
|
|
47
|
+
const count = todos.length;
|
|
48
|
+
todos = [];
|
|
49
|
+
return count;
|
|
50
|
+
}
|
|
51
|
+
function listTodos(filter = 'all') {
|
|
52
|
+
if (filter === 'done')
|
|
53
|
+
return todos.filter(t => t.done);
|
|
54
|
+
if (filter === 'pending')
|
|
55
|
+
return todos.filter(t => !t.done);
|
|
56
|
+
return [...todos];
|
|
57
|
+
}
|
|
58
|
+
function getTodo(id) {
|
|
59
|
+
return todos.find(t => t.id === id);
|
|
60
|
+
}
|
|
61
|
+
// ── Formatting helper ─────────────────────────────────────────────────────────
|
|
62
|
+
function formatTodoList(items) {
|
|
63
|
+
if (!items.length)
|
|
64
|
+
return 'No items.';
|
|
65
|
+
return items.map(t => {
|
|
66
|
+
const status = t.done ? '✓' : '○';
|
|
67
|
+
const pri = t.priority !== 'normal' ? ` [${t.priority}]` : '';
|
|
68
|
+
return `[${t.id}] ${status}${pri} ${t.text}`;
|
|
69
|
+
}).join('\n');
|
|
70
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
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.lev = lev;
|
|
8
|
+
exports.normalize = normalize;
|
|
9
|
+
exports.repairToolName = repairToolName;
|
|
10
|
+
// ── Levenshtein distance ──────────────────────────────────────────────────────
|
|
11
|
+
function lev(a, b) {
|
|
12
|
+
const m = a.length;
|
|
13
|
+
const n = b.length;
|
|
14
|
+
const dp = Array.from({ length: m + 1 }, (_, i) => Array.from({ length: n + 1 }, (_, j) => (i === 0 ? j : j === 0 ? i : 0)));
|
|
15
|
+
for (let i = 1; i <= m; i++) {
|
|
16
|
+
for (let j = 1; j <= n; j++) {
|
|
17
|
+
dp[i][j] = a[i - 1] === b[j - 1]
|
|
18
|
+
? dp[i - 1][j - 1]
|
|
19
|
+
: 1 + Math.min(dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1]);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return dp[m][n];
|
|
23
|
+
}
|
|
24
|
+
// ── Normalization ─────────────────────────────────────────────────────────────
|
|
25
|
+
// Strip common hallucination suffixes/patterns that LLMs append to tool names.
|
|
26
|
+
const SUFFIX_PATTERNS = [
|
|
27
|
+
/_\d+$/, // web_search_1, file_write_2
|
|
28
|
+
/\.(exec|run|call|tool)$/i, // file_write.exec
|
|
29
|
+
/_(exec|run|call|tool|v\d+)$/i, // shell_exec_run, web_search_v2
|
|
30
|
+
];
|
|
31
|
+
const CAMEL_TO_SNAKE_RE = /([A-Z])/g;
|
|
32
|
+
function normalize(name) {
|
|
33
|
+
let s = name.trim();
|
|
34
|
+
// camelCase → snake_case: getStocks → get_stocks, deepResearch → deep_research
|
|
35
|
+
s = s.replace(CAMEL_TO_SNAKE_RE, '_$1').toLowerCase().replace(/^_/, '');
|
|
36
|
+
// strip known hallucination suffixes
|
|
37
|
+
for (const pattern of SUFFIX_PATTERNS) {
|
|
38
|
+
s = s.replace(pattern, '');
|
|
39
|
+
}
|
|
40
|
+
return s;
|
|
41
|
+
}
|
|
42
|
+
// ── Main export ───────────────────────────────────────────────────────────────
|
|
43
|
+
/**
|
|
44
|
+
* Try to map a hallucinated/corrupted tool name to the closest valid tool.
|
|
45
|
+
*
|
|
46
|
+
* @param name - The tool name the LLM produced
|
|
47
|
+
* @param validTools - Authoritative list of valid tool names
|
|
48
|
+
* @returns A RepairResult if a match within threshold was found; null otherwise
|
|
49
|
+
*/
|
|
50
|
+
function repairToolName(name, validTools) {
|
|
51
|
+
if (validTools.includes(name))
|
|
52
|
+
return null; // already valid — nothing to do
|
|
53
|
+
const normalized = normalize(name);
|
|
54
|
+
// Exact match after normalization (e.g. getStocks → get_stocks)
|
|
55
|
+
if (validTools.includes(normalized)) {
|
|
56
|
+
return { original: name, repaired: normalized, distance: 0 };
|
|
57
|
+
}
|
|
58
|
+
// Fuzzy match: find the closest valid tool within the edit-distance threshold
|
|
59
|
+
// Threshold scales with name length: max(2, floor(len * 0.3))
|
|
60
|
+
const threshold = Math.max(2, Math.floor(normalized.length * 0.3));
|
|
61
|
+
let best = null;
|
|
62
|
+
for (const valid of validTools) {
|
|
63
|
+
const d = lev(normalized, valid);
|
|
64
|
+
if (d <= threshold && (!best || d < best.distance)) {
|
|
65
|
+
best = { repaired: valid, distance: d };
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
if (!best)
|
|
69
|
+
return null;
|
|
70
|
+
return { original: name, repaired: best.repaired, distance: best.distance };
|
|
71
|
+
}
|