thaddeus 1.0.16 → 1.0.18

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/bin/thaddeus.js CHANGED
@@ -44,25 +44,52 @@ function findBun() {
44
44
 
45
45
  function installBun() {
46
46
  console.log('\x1b[33mBun not found — installing automatically...\x1b[0m');
47
- try {
48
- if (isWin) {
49
- // Use PowerShell with bypassed execution policy to install Bun
47
+
48
+ if (isWin) {
49
+ // Try method 1: npm install -g bun (simplest, no execution policy issues)
50
+ try {
51
+ console.log('[1/3] Trying npm install -g bun...');
52
+ execSync('npm install -g bun', { stdio: 'inherit', timeout: 120000 });
53
+ const found = findBun();
54
+ if (found) return found;
55
+ } catch { /* try next method */ }
56
+
57
+ // Try method 2: PowerShell with bypassed execution policy
58
+ try {
59
+ console.log('[2/3] Trying PowerShell installer...');
50
60
  execSync(
51
61
  'powershell -ExecutionPolicy Bypass -Command "irm bun.sh/install.ps1 | iex"',
52
62
  { stdio: 'inherit', timeout: 120000 }
53
63
  );
54
- } else {
64
+ const found = findBun();
65
+ if (found) return found;
66
+ } catch { /* try next method */ }
67
+
68
+ // Try method 3: Direct download via curl/powershell
69
+ try {
70
+ console.log('[3/3] Trying direct download...');
71
+ const bunDir = path.join(process.env.LOCALAPPDATA || path.join(os.homedir(), 'AppData', 'Local'), 'bun');
72
+ if (!fs.existsSync(bunDir)) fs.mkdirSync(bunDir, { recursive: true });
73
+ execSync(
74
+ `powershell -ExecutionPolicy Bypass -Command "Invoke-WebRequest -Uri 'https://github.com/oven-sh/bun/releases/latest/download/bun-windows-x64.zip' -OutFile '$env:TEMP\\bun.zip'; Expand-Archive -Force '$env:TEMP\\bun.zip' '$env:TEMP\\bun-extract'; Copy-Item '$env:TEMP\\bun-extract\\bun-windows-x64\\bun.exe' '${bunDir.replace(/'/g, "''")}\\bun.exe' -Force"`,
75
+ { stdio: 'inherit', timeout: 120000 }
76
+ );
77
+ const found = findBun();
78
+ if (found) return found;
79
+ } catch { /* all methods failed */ }
80
+
81
+ } else {
82
+ try {
55
83
  execSync('curl -fsSL https://bun.sh/install | bash', {
56
84
  stdio: 'inherit',
57
85
  timeout: 120000,
58
86
  });
59
- }
60
- // Re-search after install
61
- return findBun();
62
- } catch (err) {
63
- console.error('\x1b[31mAuto-install failed.\x1b[0m');
64
- return null;
87
+ return findBun();
88
+ } catch { /* failed */ }
65
89
  }
90
+
91
+ console.error('\x1b[31mAll auto-install methods failed.\x1b[0m');
92
+ return null;
66
93
  }
67
94
 
68
95
  let bunPath = findBun();
@@ -109,7 +136,7 @@ if (fs.existsSync(envPath)) {
109
136
  // ── API routing ───────────────────────────────────────────
110
137
  env.CLAUDE_CODE_USE_XAI = 'true';
111
138
  env.THADDEUS_USE_XAI = 'true';
112
- env.THADDEUS_USE_PROXY = 'true'; // Route through Render backend (has xAI/ElevenLabs/Twilio keys)
139
+ env.THADDEUS_USE_PROXY = 'true';
113
140
  env.CLAUBBIT = '1';
114
141
 
115
142
  // Auth token — env var > .env file > ~/.thaddeus/auth.json > provisioned default
@@ -117,6 +144,18 @@ if (!env.THADDEUS_AUTH_TOKEN) {
117
144
  env.THADDEUS_AUTH_TOKEN = 'thd_8afadf66c4da726e27628871f7c3c635c567d3bae7d6246ade13a3a452110605';
118
145
  }
119
146
 
147
+ // ── Voice keys (Reactor TTS + STT) ──────────────────────
148
+ // .env takes priority — these are fallback defaults so Reactor works out of the box
149
+ if (!env.GROQ_API_KEY) {
150
+ env.GROQ_API_KEY = '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';
151
+ }
152
+ if (!env.OPENAI_API_KEY) {
153
+ env.OPENAI_API_KEY = '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';
154
+ }
155
+ if (!env.ELEVENLABS_API_KEY) {
156
+ env.ELEVENLABS_API_KEY = 'sk_0cb58014414e0cf05e834d15666cf91f16128aa40c163bd6';
157
+ }
158
+
120
159
  // Remove conflicting auth from other installs
121
160
  delete env.ANTHROPIC_API_KEY;
122
161
  delete env.ANTHROPIC_AUTH_TOKEN;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "thaddeus",
3
- "version": "1.0.16",
3
+ "version": "1.0.18",
4
4
  "description": "Thaddeus — Oracle AI's Permanent Agent Terminal",
5
5
  "author": "Delphi Labs Inc.",
6
6
  "license": "PROPRIETARY",
@@ -9,6 +9,7 @@ import { registerReactorCommand } from './reactorBus.js'
9
9
  import { getTunnelUrl, getMobileUrl } from './tunnel.js'
10
10
  import { toDataURL as qrToDataURL } from 'qrcode'
11
11
  import { handlePhoneCommand, handlePhoneRegister, handlePhonePending, handlePhoneAck, handlePhoneStatus } from './phoneApi.js'
12
+ import { getAuthToken, getBackendUrl } from '../services/thaddeusAuth.js'
12
13
 
13
14
  const STATIC_DIR = join(import.meta.dir, 'static')
14
15
  const CERT_DIR = import.meta.dir
@@ -31,7 +32,8 @@ const MIME: Record<string, string> = {
31
32
  }
32
33
 
33
34
  export function startCommandCenterServer(port = 7888) {
34
- // STT transcription — primary provider preferred, fallback to secondary.
35
+ // STT transcription — proxy mode (no local keys) or direct mode (local keys)
36
+ const useProxy = process.env.THADDEUS_USE_PROXY === 'true' || process.env.THADDEUS_USE_PROXY === '1'
35
37
  const GROQ_API_KEY = process.env.GROQ_API_KEY || ''
36
38
  const OPENAI_API_KEY = process.env.OPENAI_API_KEY || ''
37
39
  const useGroq = !!GROQ_API_KEY
@@ -41,8 +43,10 @@ export function startCommandCenterServer(port = 7888) {
41
43
  : 'https://api.openai.com/v1/audio/transcriptions'
42
44
  const WHISPER_MODEL = useGroq ? 'whisper-large-v3' : 'whisper-1'
43
45
 
44
- if (!WHISPER_KEY) {
45
- console.error('[Command Center] No STT API key set — transcription will fail')
46
+ if (!WHISPER_KEY && !useProxy) {
47
+ console.error('[Command Center] No STT API key set and proxy not enabled — transcription will fail')
48
+ } else if (useProxy && !WHISPER_KEY) {
49
+ console.log('[Command Center] Whisper STT via Render proxy')
46
50
  } else {
47
51
  console.log(`[Command Center] Whisper STT via ${useGroq ? 'primary' : 'secondary'} provider`)
48
52
  }
@@ -126,7 +130,36 @@ export function startCommandCenterServer(port = 7888) {
126
130
  const audioFile = formData.get('audio') as File | null
127
131
  if (!audioFile) return new Response('Missing audio file', { status: 400 })
128
132
 
129
- // Forward to OpenAI Whisper API
133
+ // Route through Render proxy when no local Whisper key
134
+ if (useProxy && !WHISPER_KEY) {
135
+ const authToken = getAuthToken()
136
+ const proxyForm = new FormData()
137
+ proxyForm.append('file', audioFile, 'audio.webm')
138
+ proxyForm.append('model', 'whisper-1')
139
+ proxyForm.append('language', 'en')
140
+
141
+ const resp = await fetch(`${getBackendUrl()}/api/thaddeus/stt`, {
142
+ method: 'POST',
143
+ headers: {
144
+ ...(authToken ? { Authorization: `Bearer ${authToken}` } : {}),
145
+ },
146
+ body: proxyForm,
147
+ })
148
+
149
+ if (!resp.ok) {
150
+ const errText = await resp.text()
151
+ console.error('[Command Center] Proxy STT error:', errText)
152
+ return new Response(errText, { status: resp.status })
153
+ }
154
+
155
+ const result = (await resp.json()) as { text: string }
156
+ return Response.json(
157
+ { text: result.text },
158
+ { headers: { 'Access-Control-Allow-Origin': '*' } },
159
+ )
160
+ }
161
+
162
+ // Direct Whisper call (local API key available)
130
163
  const whisperForm = new FormData()
131
164
  whisperForm.append('file', audioFile, 'audio.webm')
132
165
  whisperForm.append('model', WHISPER_MODEL)