@livx.cc/agentx 0.96.14 → 0.96.16

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.
@@ -13,6 +13,18 @@
13
13
  // Build: swiftc -O -o mic-aec mic-aec.swift -Xlinker -sectcreate -Xlinker __TEXT -Xlinker __info_plist -Xlinker Info.plist && codesign -fs - mic-aec
14
14
  import AVFoundation
15
15
 
16
+ // `--check-mic`: report TCC mic-authorization status WITHOUT prompting, then exit. Used by /doctor for a
17
+ // proactive readiness probe. Exit code: 0 authorized · 1 denied/restricted · 2 not-yet-determined.
18
+ if CommandLine.arguments.contains("--check-mic") {
19
+ switch AVCaptureDevice.authorizationStatus(for: .audio) {
20
+ case .authorized: print("authorized"); exit(0)
21
+ case .denied: print("denied"); exit(1)
22
+ case .restricted: print("restricted"); exit(1)
23
+ case .notDetermined: print("notDetermined"); exit(2)
24
+ @unknown default: print("unknown"); exit(2)
25
+ }
26
+ }
27
+
16
28
  // VPIO checks mic TCC explicitly (plain HAL capture may work while VPIO silently mutes) — request it
17
29
  let sem = DispatchSemaphore(value: 0)
18
30
  var granted = false
@@ -80,6 +92,14 @@ func playbackEnvNow() -> Float {
80
92
  let inFmt = input.outputFormat(forBus: 0)
81
93
  let decim = max(1, Int(inFmt.sampleRate / 16000))
82
94
  let out = FileHandle.standardOutput
95
+ FileHandle.standardError.write("input format: \(inFmt.sampleRate)Hz \(inFmt.channelCount)ch decim=\(decim)\n".data(using: .utf8)!)
96
+
97
+ // Diagnostic (stderr → surfaced only under DEBUG=VoiceIO): log from INSIDE the tap, throttled to ~once
98
+ // every 2s of audio. A GCD/runloop timer can't be used — AVAudioEngine+VPIO blocks background-queue
99
+ // timers in this process. If these lines appear → the tap fires (rms tells silence vs signal); if NONE
100
+ // appear → the CoreAudio input tap never fires (device/format dead) = no audio can reach STT.
101
+ var diagTaps = 0
102
+ var diagAcc = 0 // frames since last log (×decim ≈ input samples) → throttle by input sample rate
83
103
 
84
104
  input.installTap(onBus: 0, bufferSize: 2048, format: inFmt) { buf, _ in
85
105
  guard let ch = buf.floatChannelData else { return }
@@ -129,6 +149,11 @@ input.installTap(onBus: 0, bufferSize: 2048, format: inFmt) { buf, _ in
129
149
  let gate = gateEnabled && audible && rms < threshold // user speech must clearly dominate the expected residue
130
150
  gateLock.unlock()
131
151
  if gate { for k in 0..<pcm.count { pcm[k] = 0 } } // keep the stream's timing — send silence, not nothing
152
+ diagTaps += 1; diagAcc += n
153
+ if diagAcc >= Int(inFmt.sampleRate) * 2 { // ~every 2s of input audio
154
+ FileHandle.standardError.write("tap: \(diagTaps) firings/2s, rms=\(Int(rms)), gate=\(gate)\n".data(using: .utf8)!)
155
+ diagTaps = 0; diagAcc = 0
156
+ }
132
157
  pcm.withUnsafeBufferPointer { p in
133
158
  out.write(Data(buffer: p))
134
159
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@livx.cc/agentx",
3
- "version": "0.96.14",
3
+ "version": "0.96.16",
4
4
  "description": "Edge-native AI agent runtime — drives a virtual filesystem via any LLM (ai.libx.js). Same bytes run in node, browser, or edge.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",