@astra-code/astra-ai 0.1.3 → 0.1.5

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.
@@ -281,7 +281,11 @@ export class BackendClient {
281
281
  return;
282
282
  }
283
283
  try {
284
- yield JSON.parse(data) as AgentEvent;
284
+ const parsed = JSON.parse(data) as AgentEvent;
285
+ if (parsed.type === "done") {
286
+ return;
287
+ }
288
+ yield parsed;
285
289
  } catch {
286
290
  // Ignore malformed chunks and keep stream alive.
287
291
  }
package/src/lib/voice.ts CHANGED
@@ -39,7 +39,8 @@ const captureAudioChunk = async (seconds: number): Promise<string> => {
39
39
  if (process.platform === "darwin") {
40
40
  // Prefer ffmpeg on macOS (works on Apple Silicon/Homebrew setups).
41
41
  if (commandExists("ffmpeg")) {
42
- cmd = `ffmpeg -hide_banner -loglevel error -f avfoundation -i ":0" -ar 16000 -ac 1 -t ${seconds} "${outPath}"`;
42
+ const micDevice = process.env.ASTRA_STT_DEVICE?.trim() || ":0";
43
+ cmd = `ffmpeg -hide_banner -loglevel error -f avfoundation -i "${micDevice}" -ar 16000 -ac 1 -t ${seconds} "${outPath}"`;
43
44
  } else if (commandExists("rec")) {
44
45
  cmd = `rec -q -r 16000 -c 1 "${outPath}" trim 0 ${seconds}`;
45
46
  } else {
@@ -62,12 +63,21 @@ const captureAudioChunk = async (seconds: number): Promise<string> => {
62
63
  cmd = cmd.replaceAll("{output}", outPath).replaceAll("{seconds}", String(seconds));
63
64
  }
64
65
 
66
+ // #region agent log
67
+ fetch('http://127.0.0.1:7573/ingest/fdd4f018-1ba3-4303-b1bb-375443267476',{method:'POST',headers:{'Content-Type':'application/json','X-Debug-Session-Id':'17f1ea'},body:JSON.stringify({sessionId:'17f1ea',runId:'voice_run_2',hypothesisId:'H6',location:'voice.ts:captureAudioChunk',message:'capture command selected',data:{platform:process.platform,seconds,usesCustom:Boolean(custom),cmdPreview:cmd.slice(0,180)},timestamp:Date.now()})}).catch(()=>{});
68
+ // #endregion
65
69
  await runShell(cmd);
70
+ // #region agent log
71
+ fetch('http://127.0.0.1:7573/ingest/fdd4f018-1ba3-4303-b1bb-375443267476',{method:'POST',headers:{'Content-Type':'application/json','X-Debug-Session-Id':'17f1ea'},body:JSON.stringify({sessionId:'17f1ea',runId:'voice_run_2',hypothesisId:'H6',location:'voice.ts:captureAudioChunk',message:'capture command completed',data:{outputPath:outPath},timestamp:Date.now()})}).catch(()=>{});
72
+ // #endregion
66
73
  return outPath;
67
74
  };
68
75
 
69
76
  const transcribeAudioFile = async (filePath: string): Promise<string> => {
70
77
  const bytes = await readFile(filePath);
78
+ // #region agent log
79
+ fetch('http://127.0.0.1:7573/ingest/fdd4f018-1ba3-4303-b1bb-375443267476',{method:'POST',headers:{'Content-Type':'application/json','X-Debug-Session-Id':'17f1ea'},body:JSON.stringify({sessionId:'17f1ea',runId:'voice_run_2',hypothesisId:'H7',location:'voice.ts:transcribeAudioFile',message:'audio chunk loaded',data:{filePath,byteLength:bytes.length},timestamp:Date.now()})}).catch(()=>{});
80
+ // #endregion
71
81
  const file = new File([bytes], basename(filePath), {type: "audio/wav"});
72
82
 
73
83
  // Backend proxy only: backend holds provider secrets.
@@ -83,12 +93,19 @@ const transcribeAudioFile = async (filePath: string): Promise<string> => {
83
93
  headers: {Authorization: `Bearer ${token}`},
84
94
  body: form
85
95
  });
96
+ // #region agent log
97
+ fetch('http://127.0.0.1:7573/ingest/fdd4f018-1ba3-4303-b1bb-375443267476',{method:'POST',headers:{'Content-Type':'application/json','X-Debug-Session-Id':'17f1ea'},body:JSON.stringify({sessionId:'17f1ea',runId:'voice_run_2',hypothesisId:'H7',location:'voice.ts:transcribeAudioFile',message:'backend transcribe response',data:{status:response.status,ok:response.ok},timestamp:Date.now()})}).catch(()=>{});
98
+ // #endregion
86
99
  if (!response.ok) {
87
100
  const detail = (await response.text()).slice(0, 400);
88
101
  throw new Error(`Backend transcription failed ${response.status}: ${detail}`);
89
102
  }
90
103
  const data = (await response.json()) as {text?: string};
91
- return String(data.text ?? "").trim();
104
+ const out = String(data.text ?? "").trim();
105
+ // #region agent log
106
+ fetch('http://127.0.0.1:7573/ingest/fdd4f018-1ba3-4303-b1bb-375443267476',{method:'POST',headers:{'Content-Type':'application/json','X-Debug-Session-Id':'17f1ea'},body:JSON.stringify({sessionId:'17f1ea',runId:'voice_run_2',hypothesisId:'H8',location:'voice.ts:transcribeAudioFile',message:'transcribe text received',data:{textLen:out.length,textPreview:out.slice(0,80)},timestamp:Date.now()})}).catch(()=>{});
107
+ // #endregion
108
+ return out;
92
109
  };
93
110
 
94
111
  /**
@@ -38,5 +38,16 @@ export type AgentEvent =
38
38
  }
39
39
  | {type: "credits_update"; remaining?: number; cost?: number}
40
40
  | {type: "credits_exhausted"; message?: string}
41
+ | {
42
+ type: "continuation_check";
43
+ allow_continue?: boolean;
44
+ reason?: string;
45
+ recommendation?: string;
46
+ iteration?: number;
47
+ consecutive_read_only_iterations?: number;
48
+ threshold?: number;
49
+ analysis_intent?: boolean;
50
+ tool_names_used?: string[];
51
+ }
41
52
  | {type: "error"; error?: string; content?: string}
42
53
  | {type: string; [key: string]: unknown};