aiden-runtime 3.18.0 → 3.19.4

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.
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ // core/tools/nowPlaying.ts — Live media session query via Windows WinRT
3
+ // Uses GlobalSystemMediaTransportControlsSessionManager (works for Spotify,
4
+ // YouTube in browser, Windows Media Player, and any SMTC-registered app).
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.getNowPlaying = getNowPlaying;
7
+ const child_process_1 = require("child_process");
8
+ const util_1 = require("util");
9
+ const execAsync = (0, util_1.promisify)(child_process_1.exec);
10
+ // PowerShell uses System.WindowsRuntimeSystemExtensions.AsTask to bridge
11
+ // WinRT IAsyncOperation<T> into a .NET Task — required because PS5.1 cannot
12
+ // await WinRT async operations natively via .GetAwaiter().
13
+ const PS_SCRIPT = `
14
+ Add-Type -AssemblyName System.Runtime.WindowsRuntime
15
+ function Await($WinRtTask, $ResultType) {
16
+ $m = ([System.WindowsRuntimeSystemExtensions].GetMethods() | Where-Object {
17
+ $_.Name -eq 'AsTask' -and
18
+ $_.GetParameters().Count -eq 1 -and
19
+ $_.GetParameters()[0].ParameterType.Name -eq 'IAsyncOperation\`1'
20
+ })[0]
21
+ $m = $m.MakeGenericMethod($ResultType)
22
+ $t = $m.Invoke($null, @($WinRtTask))
23
+ $t.Wait(-1) | Out-Null
24
+ $t.Result
25
+ }
26
+ $mgType = [Windows.Media.Control.GlobalSystemMediaTransportControlsSessionManager,Windows.Media.Control,ContentType=WindowsRuntime]
27
+ $mgr = Await ($mgType::RequestAsync()) $mgType
28
+ $s = $mgr.GetCurrentSession()
29
+ if ($s) {
30
+ $pType = [Windows.Media.Control.GlobalSystemMediaTransportControlsSessionMediaProperties,Windows.Media.Control,ContentType=WindowsRuntime]
31
+ $p = Await ($s.TryGetMediaPropertiesAsync()) $pType
32
+ $pb = $s.GetPlaybackInfo()
33
+ @{ app=$s.SourceAppUserModelId; title=$p.Title; artist=$p.Artist; album=$p.AlbumTitle; isPlaying=($pb.PlaybackStatus -eq 'Playing'); playbackStatus=$pb.PlaybackStatus.ToString() } | ConvertTo-Json -Compress
34
+ } else {
35
+ '{"isPlaying":false,"message":"No media session active"}'
36
+ }
37
+ `.trim();
38
+ async function getNowPlaying() {
39
+ const { stdout } = await execAsync(PS_SCRIPT, {
40
+ shell: 'powershell.exe',
41
+ timeout: 5000,
42
+ });
43
+ const raw = stdout.trim();
44
+ if (!raw)
45
+ return { isPlaying: false, message: 'No output from media session query' };
46
+ const parsed = JSON.parse(raw);
47
+ // Normalize app ID to a friendly name where possible
48
+ if (parsed.app) {
49
+ const id = parsed.app.toLowerCase();
50
+ if (id.includes('spotify'))
51
+ parsed.app = 'Spotify';
52
+ else if (id.includes('msedge'))
53
+ parsed.app = 'Microsoft Edge';
54
+ else if (id.includes('chrome'))
55
+ parsed.app = 'Google Chrome';
56
+ else if (id.includes('firefox'))
57
+ parsed.app = 'Firefox';
58
+ else if (id.includes('vlc'))
59
+ parsed.app = 'VLC';
60
+ else if (id.includes('groove'))
61
+ parsed.app = 'Groove Music';
62
+ else if (id.includes('mediaplay'))
63
+ parsed.app = 'Windows Media Player';
64
+ }
65
+ return parsed;
66
+ }
@@ -2,4 +2,4 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.VERSION = void 0;
4
4
  // AUTO-GENERATED by scripts/inject-version.js — do not edit by hand
5
- exports.VERSION = '3.18.0';
5
+ exports.VERSION = '3.19.4';
@@ -49,6 +49,7 @@ const openrouter_1 = require("./openrouter");
49
49
  const gemini_1 = require("./gemini");
50
50
  const boa_1 = require("./boa");
51
51
  const cerebras_1 = require("./cerebras");
52
+ const mistral_1 = require("./mistral");
52
53
  const custom_1 = require("./custom");
53
54
  // Use AIDEN_CONFIG_DIR when injected by Electron CLI mode, otherwise fall back to cwd/config
54
55
  const CONFIG_PATH = path.join(process.env.AIDEN_CONFIG_DIR || path.join(process.cwd(), 'config'), 'devos.config.json');
@@ -78,6 +79,15 @@ function defaultConfig() {
78
79
  rateLimited: false,
79
80
  usageCount: 0,
80
81
  },
82
+ {
83
+ name: 'mistral',
84
+ provider: 'mistral',
85
+ key: 'env:MISTRAL_API_KEY',
86
+ model: 'mistral-large-latest',
87
+ enabled: false,
88
+ rateLimited: false,
89
+ usageCount: 0,
90
+ },
81
91
  ],
82
92
  },
83
93
  routing: { mode: 'auto', fallbackToOllama: true },
@@ -139,6 +149,8 @@ function getActiveProvider() {
139
149
  return { provider: (0, boa_1.createBOAProvider)(key), model: apiConfig.model || 'llama-3.3-70b', userName };
140
150
  case 'cerebras':
141
151
  return { provider: (0, cerebras_1.createCerebrasProvider)(key), model: apiConfig.model || 'llama3.1-8b', userName };
152
+ case 'mistral':
153
+ return { provider: (0, mistral_1.createMistralProvider)(key), model: apiConfig.model || 'mistral-large-latest', userName };
142
154
  case 'custom': {
143
155
  const baseUrl = apiConfig.baseUrl || 'http://localhost:11434/v1';
144
156
  return { provider: (0, custom_1.createCustomProvider)(baseUrl, key, apiConfig.name), model: apiConfig.model || 'gpt-4o-mini', userName };
@@ -0,0 +1,121 @@
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.createMistralProvider = createMistralProvider;
8
+ const MISTRAL_CHAT_COMPLETIONS_URL = 'https://api.mistral.ai/v1/chat/completions';
9
+ function extractContent(content) {
10
+ if (typeof content === 'string')
11
+ return content;
12
+ if (!Array.isArray(content))
13
+ return '';
14
+ return content
15
+ .map(part => {
16
+ if (typeof part === 'string')
17
+ return part;
18
+ if (part && typeof part === 'object' && 'text' in part) {
19
+ return typeof part.text === 'string' ? part.text : '';
20
+ }
21
+ return '';
22
+ })
23
+ .join('');
24
+ }
25
+ function parseToolArguments(args) {
26
+ if (!args)
27
+ return {};
28
+ if (typeof args === 'object')
29
+ return args;
30
+ if (typeof args !== 'string')
31
+ return {};
32
+ try {
33
+ return JSON.parse(args);
34
+ }
35
+ catch {
36
+ return {};
37
+ }
38
+ }
39
+ function createMistralProvider(apiKey) {
40
+ const headers = () => ({
41
+ 'Content-Type': 'application/json',
42
+ 'Authorization': `Bearer ${apiKey}`,
43
+ });
44
+ return {
45
+ name: 'mistral',
46
+ async generateWithTools(messages, model, tools) {
47
+ const res = await fetch(MISTRAL_CHAT_COMPLETIONS_URL, {
48
+ method: 'POST',
49
+ headers: headers(),
50
+ body: JSON.stringify({
51
+ model,
52
+ messages,
53
+ tools: tools.map(t => ({ type: 'function', function: t })),
54
+ tool_choice: 'auto',
55
+ stream: false,
56
+ }),
57
+ });
58
+ const data = await res.json();
59
+ if (!res.ok)
60
+ throw new Error(`${res.status}: ${JSON.stringify(data)}`);
61
+ const message = data.choices?.[0]?.message;
62
+ const toolCalls = (message?.tool_calls || []).map((tc) => ({
63
+ name: tc.function.name,
64
+ arguments: parseToolArguments(tc.function.arguments),
65
+ }));
66
+ return { content: extractContent(message?.content), toolCalls };
67
+ },
68
+ async generate(messages, model) {
69
+ const res = await fetch(MISTRAL_CHAT_COMPLETIONS_URL, {
70
+ method: 'POST',
71
+ headers: headers(),
72
+ body: JSON.stringify({ model, messages, stream: false }),
73
+ });
74
+ if (!res.ok) {
75
+ const err = await res.text();
76
+ throw new Error(`${res.status}: ${err}`);
77
+ }
78
+ const data = await res.json();
79
+ return extractContent(data?.choices?.[0]?.message?.content);
80
+ },
81
+ async generateStream(messages, model, onToken) {
82
+ const res = await fetch(MISTRAL_CHAT_COMPLETIONS_URL, {
83
+ method: 'POST',
84
+ headers: headers(),
85
+ body: JSON.stringify({ model, messages, stream: true }),
86
+ });
87
+ if (!res.ok) {
88
+ const err = await res.text();
89
+ throw new Error(`${res.status}: ${err}`);
90
+ }
91
+ if (!res.body)
92
+ return;
93
+ const reader = res.body.getReader();
94
+ const decoder = new TextDecoder();
95
+ let buf = '';
96
+ while (true) {
97
+ const { done, value } = await reader.read();
98
+ if (done)
99
+ break;
100
+ buf += decoder.decode(value, { stream: true });
101
+ const lines = buf.split('\n');
102
+ buf = lines.pop() ?? '';
103
+ for (const line of lines) {
104
+ if (!line.startsWith('data: '))
105
+ continue;
106
+ const raw = line.replace('data: ', '').trim();
107
+ if (raw === '[DONE]')
108
+ return;
109
+ try {
110
+ const parsed = JSON.parse(raw);
111
+ const content = parsed?.choices?.[0]?.delta?.content;
112
+ const token = extractContent(content);
113
+ if (token)
114
+ onToken(token);
115
+ }
116
+ catch { /* skip malformed SSE chunks */ }
117
+ }
118
+ }
119
+ },
120
+ };
121
+ }
@@ -30,6 +30,7 @@ const gemini_1 = require("./gemini");
30
30
  const cerebras_1 = require("./cerebras");
31
31
  const nvidia_1 = require("./nvidia");
32
32
  const boa_1 = require("./boa");
33
+ const mistral_1 = require("./mistral");
33
34
  const custom_1 = require("./custom");
34
35
  const modelDiscovery_1 = require("../core/modelDiscovery");
35
36
  const modelRegistry_1 = require("../core/modelRegistry");
@@ -115,6 +116,7 @@ function buildProvider(entry) {
115
116
  case 'cerebras': return (0, cerebras_1.createCerebrasProvider)(key);
116
117
  case 'nvidia': return (0, nvidia_1.createNvidiaProvider)(key);
117
118
  case 'boa': return (0, boa_1.createBOAProvider)(key);
119
+ case 'mistral': return (0, mistral_1.createMistralProvider)(key);
118
120
  case 'custom': return (0, custom_1.createCustomProvider)(entry.baseUrl || '', key, entry.name);
119
121
  default: return ollama_1.ollamaProvider;
120
122
  }
@@ -370,8 +372,8 @@ function getModelForTask(task, message) {
370
372
  return k.length > 0;
371
373
  });
372
374
  // Planner + Responder: walk ALL apis in config order (handles multiple slots per provider).
373
- // Cerebras/nvidia excluded — 8B models cannot follow complex SOUL-based prompts.
374
- const CHAT_EXCLUDED = new Set(['cerebras', 'nvidia']);
375
+ // Cerebras excluded — 8B models cannot follow complex SOUL-based prompts. NVIDIA promoted to chat chain.
376
+ const CHAT_EXCLUDED = new Set(['cerebras']);
375
377
  if (task === 'planner' || task === 'responder') {
376
378
  let chatApis = available.filter(a => !CHAT_EXCLUDED.has(a.provider));
377
379
  // Primary provider pinning — move primary to front of chain