aboutsummaryrefslogtreecommitdiff
path: root/modules/core/core-bundle.js
diff options
context:
space:
mode:
authorAgando <roduccomm@gmail.com>2026-06-23 18:00:58 +0200
committerAgando <roduccomm@gmail.com>2026-06-23 18:00:58 +0200
commit168a7bc6d50023215f75fa8a0d95362473cfe033 (patch)
tree7351abfcaff59a6fcebf19ea322a77eda9b6ed6b /modules/core/core-bundle.js
parente9b75cd3a801689f57bc8a013f14c058e57e3b46 (diff)
auto: 2026-06-23_18:00 changes
Diffstat (limited to 'modules/core/core-bundle.js')
-rw-r--r--modules/core/core-bundle.js167
1 files changed, 160 insertions, 7 deletions
diff --git a/modules/core/core-bundle.js b/modules/core/core-bundle.js
index 175df87..13330ab 100644
--- a/modules/core/core-bundle.js
+++ b/modules/core/core-bundle.js
@@ -3473,6 +3473,7 @@ Only output XML function calls for tool tasks. If no tool is needed, answer norm
this._safeRegister('PredictorModule', 'predictor');
this._safeRegister('WorldModelModule', 'world model');
this._safeRegister('ServerMonitorModule', 'server monitor');
+ this._safeRegister('SmartContextModule', 'smart context');
this._safeRegister('SimpleGUIModule', 'simple GUI builder');
// v4.5.47: Critical ext modules promoted to boot path
this._safeRegister('EditorModule', 'editor');
@@ -3520,6 +3521,7 @@ Only output XML function calls for tool tasks. If no tool is needed, answer norm
FileManagerModule: typeof FileManagerModule !== 'undefined' ? FileManagerModule : undefined,
DiffModule: typeof DiffModule !== 'undefined' ? DiffModule : undefined,
BusyBoxModule: typeof BusyBoxModule !== 'undefined' ? BusyBoxModule : undefined,
+ SmartContextModule: typeof SmartContextModule !== 'undefined' ? SmartContextModule : undefined,
};
const cls = registry[className];
if (typeof cls === 'undefined') {
@@ -8197,6 +8199,7 @@ buildSystemPrompt() {
async agenticLoop(messages) {
let toolTurns = 0;
const _seenCalls = new Map(); // v4.5.66: loop detection — track repeated tool calls
+ const _loopWindow = 30000; // 30s window for loop detection
while (toolTurns < this.MAX_TOOL_TURNS) {
if (this._cancelled) { this.terminal.print('AI loop cancelled', 'warning'); return { finalAnswer: null, toolTurns }; }
toolTurns++;
@@ -8223,16 +8226,22 @@ buildSystemPrompt() {
return { finalAnswer: text, toolTurns };
}
if (res.tool_calls && res.tool_calls.length > 0) {
- // v4.5.66: Loop detection — break if AI repeats same tool+args 3+ times
- // Reset per-turn so legitimate retries across turns don't false-positive
- _seenCalls.clear();
+ // v4.5.66: Loop detection — break if AI repeats same tool+args 6+ times in 30s
+ // Accumulates across turns (no clear) so real loops are caught,
+ // but time-windowed so legitimate retries across separate queries don't false-positive
+ const now = Date.now();
let looping = false;
for (const tc of res.tool_calls) {
const sig = tc.function.name + ':' + (tc.function.arguments || '');
- const count = (_seenCalls.get(sig) || 0) + 1;
- _seenCalls.set(sig, count);
- if (count >= 3) {
- this.terminal.print(`🔄 Loop detected: ${tc.function.name} called ${count}x with same args — breaking loop`, 'warning');
+ let entry = _seenCalls.get(sig);
+ if (!entry || (now - entry.ts) > _loopWindow) {
+ entry = { count: 0, ts: now };
+ }
+ entry.count++;
+ entry.ts = now;
+ _seenCalls.set(sig, entry);
+ if (entry.count >= 6) {
+ this.terminal.print(`🔄 Loop detected: ${tc.function.name} called ${entry.count}x with same args in 30s — breaking loop`, 'warning');
looping = true;
break;
}
@@ -16271,4 +16280,148 @@ if (typeof window !== 'undefined') {
window.NeuralVFSModule = NeuralVFSModule;
}
+/* === module-smartctx.js === */
+// Extracted from newOS4 index.html — SmartContextModule
+ class SmartContextModule {
+ constructor() {
+ this.commands = {}; this.terminal = null;
+ this.contextProfiles = this.loadProfiles(); this.activeProfile = this.loadActiveProfile();
+ }
+ getHelpInfo() {
+ return {
+ 'context': 'context [name] — Set or view current context profile',
+ 'contexts': 'contexts — List all available context profiles',
+ 'context-new': 'context-new <name> <displayName> <systemPrompt> — Create a new context profile',
+ 'context-delete': 'context-delete <name> — Delete a context profile',
+ 'smart-ask': 'smart-ask <question> — Ask a question using the active context'
+ };
+ }
+ loadProfiles() {
+ try {
+ const saved = localStorage.getItem('webx11_context_profiles');
+ return saved ? JSON.parse(saved) : this.getDefaultProfiles();
+ } catch (e) { return this.getDefaultProfiles(); }
+ }
+ saveProfiles() {
+ localStorage.setItem('webx11_context_profiles', JSON.stringify(this.contextProfiles));
+ }
+ loadActiveProfile() {
+ try {
+ const saved = localStorage.getItem('webx11_active_context_profile');
+ if (saved && this.contextProfiles[saved]) return saved;
+ } catch (e) {}
+ return null;
+ }
+ saveActiveProfile() {
+ try {
+ if (this.activeProfile) {
+ localStorage.setItem('webx11_active_context_profile', this.activeProfile);
+ } else {
+ localStorage.removeItem('webx11_active_context_profile');
+ }
+ } catch (e) {}
+ }
+ getDefaultProfiles() {
+ return {
+ 'coding': { name: 'Coding Assistant', systemPrompt: "You are an expert programmer.", temperature: 0.7 },
+ 'debug': { name: 'Debug Helper', systemPrompt: "You are a debugging expert.", temperature: 0.5 },
+ 'creative': { name: 'Creative Writer', systemPrompt: "You are a creative writer.", temperature: 0.9 },
+ 'technical': { name: 'Technical Docs', systemPrompt: "You are a technical writer.", temperature: 0.3 },
+ 'chat': { name: 'Casual Chat', systemPrompt: "You are a friendly assistant.", temperature: 0.8 }
+ };
+ }
+ registerCommands() {
+ this.commands['context'] = (args) => this.setContext(args);
+ this.commands['contexts'] = () => this.listContexts();
+ this.commands['context-new'] = (args) => this.createContext(args);
+ this.commands['context-delete'] = (args) => this.deleteContext(args);
+ this.commands['smart-ask'] = (args) => this.smartAsk(args);
+ }
+ setContext(args) {
+ if (!args[0]) {
+ this.terminal.print(`Current context: ${this.activeProfile || 'none'}`, "info"); return;
+ }
+ if (this.contextProfiles[args[0]]) {
+ this.activeProfile = args[0];
+ this.saveActiveProfile();
+ this.terminal.print(`Context set to: ${this.contextProfiles[args[0]].name}`, "success");
+ } else {
+ this.terminal.print(`Profile '${args[0]}' not found`, "error");
+ }
+ }
+ listContexts() {
+ this.terminal.print("=== Context Profiles ===", "info");
+ Object.entries(this.contextProfiles).forEach(([key, profile]) => {
+ const active = key === this.activeProfile ? ' ✅' : '';
+ this.terminal.print(`${key}: ${profile.name}${active}`);
+ });
+ }
+ createContext(args) {
+ if (args.length < 3) {
+ this.terminal.print("Usage: context-new <name> <displayName> <systemPrompt>", "warning"); return;
+ }
+ const name = args[0], displayName = args[1], systemPrompt = args.slice(2).join(' ');
+ this.contextProfiles[name] = { name: displayName, systemPrompt, temperature: 0.7 };
+ this.saveProfiles();
+ this.terminal.print(`Context profile '${name}' created`, "success");
+ }
+ deleteContext(args) {
+ if (!args[0]) {
+ this.terminal.print("Usage: context-delete <name>", "warning"); return;
+ }
+ if (this.contextProfiles[args[0]]) {
+ delete this.contextProfiles[args[0]];
+ this.saveProfiles();
+ if (this.activeProfile === args[0]) { this.activeProfile = null; }
+ this.terminal.print(`Context profile '${args[0]}' deleted`, "success");
+ } else {
+ this.terminal.print(`Profile '${args[0]}' not found`, "error");
+ }
+ }
+ async smartAsk(args) {
+ if (!args[0]) {
+ this.terminal.print("Usage: smart-ask <your-question>", "warning"); return;
+ }
+ let systemPrompt = "You are a helpful assistant.";
+ let temperature = 0.7;
+ if (this.activeProfile && this.contextProfiles[this.activeProfile]) {
+ const profile = this.contextProfiles[this.activeProfile];
+ systemPrompt = profile.systemPrompt;
+ temperature = profile.temperature || 0.7;
+ this.terminal.print(`Using context: ${profile.name} (temp: ${temperature})`, "info");
+ }
+ // Use agentic loop via the AI assistant module for tool-enabled responses
+ const aiModule = this.terminal?.moduleManager?.modules?.WebX11AIAssistantModule;
+ if (aiModule) {
+ // Set temperature on ollamaManager modelParams temporarily
+ const om = this.terminal.ollamaManager;
+ const savedTemp = om.modelParams ? om.modelParams.temperature : undefined;
+ if (om.modelParams) {
+ om.modelParams.temperature = temperature;
+ }
+ try {
+ const messages = [
+ { role: 'system', content: systemPrompt },
+ { role: 'user', content: args.join(' ') }
+ ];
+ const result = await om.chatWithTools(messages, aiModule.getToolDefinitions());
+ if (result && result.message) {
+ this.terminal.printAIResponse(result.message.content || '(no response)');
+ } else if (result && result.error) {
+ this.terminal.print(`⚠️ AI error: ${result.error}`, 'error');
+ }
+ } finally {
+ if (om.modelParams && savedTemp !== undefined) {
+ om.modelParams.temperature = savedTemp;
+ }
+ }
+ } else {
+ // Fallback: simple chat with temperature
+ const om = this.terminal.ollamaManager;
+ const fullPrompt = `${systemPrompt}\n\nUser: ${args.join(' ')}`;
+ await om.chat(fullPrompt);
+ }
+ }
+ }
+
/* === end core module bundle === */