@infilectai/aira 0.0.0-stage → 0.1.0

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.
Files changed (57) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +74 -2
  3. package/bin/aira-capture +0 -0
  4. package/dist/attribution.d.ts +118 -0
  5. package/dist/attribution.d.ts.map +1 -0
  6. package/dist/attribution.js +626 -0
  7. package/dist/attribution.js.map +1 -0
  8. package/dist/audio.d.ts +26 -0
  9. package/dist/audio.d.ts.map +1 -0
  10. package/dist/audio.js +172 -0
  11. package/dist/audio.js.map +1 -0
  12. package/dist/brain.d.ts +11 -0
  13. package/dist/brain.d.ts.map +1 -0
  14. package/dist/brain.js +70 -0
  15. package/dist/brain.js.map +1 -0
  16. package/dist/capture.d.ts +48 -0
  17. package/dist/capture.d.ts.map +1 -0
  18. package/dist/capture.js +195 -0
  19. package/dist/capture.js.map +1 -0
  20. package/dist/engine.d.ts +61 -0
  21. package/dist/engine.d.ts.map +1 -0
  22. package/dist/engine.js +471 -0
  23. package/dist/engine.js.map +1 -0
  24. package/dist/eyes.d.ts +60 -0
  25. package/dist/eyes.d.ts.map +1 -0
  26. package/dist/eyes.js +173 -0
  27. package/dist/eyes.js.map +1 -0
  28. package/dist/index.d.ts +11 -0
  29. package/dist/index.d.ts.map +1 -0
  30. package/dist/index.js +9 -0
  31. package/dist/index.js.map +1 -0
  32. package/dist/lockfile.d.ts +14 -0
  33. package/dist/lockfile.d.ts.map +1 -0
  34. package/dist/lockfile.js +38 -0
  35. package/dist/lockfile.js.map +1 -0
  36. package/dist/providers.d.ts +162 -0
  37. package/dist/providers.d.ts.map +1 -0
  38. package/dist/providers.js +374 -0
  39. package/dist/providers.js.map +1 -0
  40. package/dist/transport.d.ts +14 -0
  41. package/dist/transport.d.ts.map +1 -0
  42. package/dist/transport.js +44 -0
  43. package/dist/transport.js.map +1 -0
  44. package/dist/types.d.ts +175 -0
  45. package/dist/types.d.ts.map +1 -0
  46. package/dist/types.js +2 -0
  47. package/dist/types.js.map +1 -0
  48. package/dist/vectors.d.ts +10 -0
  49. package/dist/vectors.d.ts.map +1 -0
  50. package/dist/vectors.js +66 -0
  51. package/dist/vectors.js.map +1 -0
  52. package/native/AiraCapture.swift +1142 -0
  53. package/native/Info.plist +26 -0
  54. package/native/NativeMeetingScraper.swift +1277 -0
  55. package/package.json +84 -4
  56. package/scripts/build-capture.cjs +57 -0
  57. package/scripts/postinstall.cjs +29 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 InfilectAI
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,75 @@
1
- # Temporary Holding Version
1
+ # @infilectai/aira
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Standalone, npm-publishable macOS meeting detection, speaker attribution, and audio capture SDK.
4
+
5
+ `@infilectai/aira` ships a tiny (~450 KB), zero-dependency native macOS helper (`bin/aira-capture`) that handles:
6
+ - **Meeting Detection**: Google Meet, Zoom, and Microsoft Teams (`watchActiveMeetings`, `onMeetingDetected`)
7
+ - **Native Speaker & Roster Scraping**: 250ms macOS Accessibility + DOM inspection fused with local microphone RMS activity
8
+ - **Zero-Screen-Recording Audio Capture**: CoreAudio Process Tap (`CATapDescription` + `AudioHardwareCreateProcessTap`, macOS 14.2+) with `ScreenCaptureKit` fallback
9
+
10
+ Transcription (STT) and Diarization are **100% pluggable** — connect any OpenAI-compatible HTTP endpoint, WebSocket STT stream, custom callback, or [InfilectAI/AiraEngine][engine] as an optional local on-device compute provider.
11
+
12
+ [engine]: https://github.com/InfilectAI/AiraEngine
13
+
14
+ ## Quick Start (Pluggable Endpoints)
15
+
16
+ ```ts
17
+ import { Aira, HttpSTTProvider, HttpDiarizationProvider } from '@infilectai/aira'
18
+
19
+ // 1. Plug in ANY OpenAI-compatible STT endpoint (OpenAI, Groq, local whisper.cpp, FastAPI, etc.)
20
+ // and optional Diarization endpoint:
21
+ const aira = await Aira.create({
22
+ stt: {
23
+ url: 'https://api.openai.com/v1/audio/transcriptions',
24
+ apiKey: process.env.OPENAI_API_KEY,
25
+ model: 'whisper-1',
26
+ },
27
+ // Optional: plug in any /v1/audio/diarize endpoint or callback
28
+ diarize: {
29
+ url: 'http://127.0.0.1:8000/v1/audio/diarize',
30
+ },
31
+ })
32
+
33
+ // 2. Or plug in a custom callback for any SDK (Deepgram, ElevenLabs, AssemblyAI, etc.):
34
+ const airaWithCallback = await Aira.create({
35
+ stt: async (wavBuffer) => {
36
+ // Call any STT SDK or API and return text or { text, segments }
37
+ return { text: 'Hello team', segments: [{ id: 0, start: 0, end: 1.5, text: 'Hello team' }] }
38
+ },
39
+ })
40
+
41
+ // 3. Detect meetings and start live speaker-attributed transcription:
42
+ aira.onMeetingDetected((meeting) => {
43
+ console.log(`New meeting: ${meeting.title} on ${meeting.platform}`)
44
+ aira.startMeeting(meeting)
45
+ })
46
+
47
+ aira.on('transcript', (event) => {
48
+ console.log(`[${event.name || 'Speaker'}] ${event.text}`)
49
+ })
50
+ ```
51
+
52
+ ## Using `AiraEngine` as a Local On-Device Provider
53
+
54
+ If you run [InfilectAI/AiraEngine][engine] locally (WhisperKit `whisper-large-v3` + SpeakerKit Pyannote + Gemma 4), pass its `baseUrl` or `AiraEngineProvider`:
55
+
56
+ ```ts
57
+ import { Aira, AiraEngineProvider } from '@infilectai/aira'
58
+
59
+ const engineProvider = new AiraEngineProvider('http://127.0.0.1:50060')
60
+ const aira = await Aira.create({
61
+ baseUrl: 'http://127.0.0.1:50060',
62
+ stt: engineProvider,
63
+ diarize: engineProvider,
64
+ })
65
+ ```
66
+
67
+ ## Build & Pack
68
+
69
+ ```sh
70
+ npm install
71
+ npm run build
72
+ npm pack --dry-run
73
+ ```
74
+
75
+ `npm run build` compiles `native/AiraCapture.swift` + `native/NativeMeetingScraper.swift` into `bin/aira-capture` (~450 KB, linked only against Apple system frameworks) and compiles TypeScript to `dist/`.
Binary file
@@ -0,0 +1,118 @@
1
+ import type { CaptureAudioPayload, CaptureRosterPayload, CaptureSpeakerPayload } from './capture.js';
2
+ import { type DiarizationProvider, type STTProvider } from './providers.js';
3
+ import type { EyesEvent, Participant, TranscribeOptions } from './types.js';
4
+ export interface SpeakerSpan {
5
+ participantId: string;
6
+ name: string;
7
+ t0: number;
8
+ t1: number;
9
+ source: string;
10
+ }
11
+ export interface StitchedDiarizeSegment {
12
+ t0: number;
13
+ t1: number;
14
+ speakerId: string;
15
+ }
16
+ /**
17
+ * Rolling-window cross-batch cluster stitcher for any stateless `DiarizationProvider`.
18
+ * Matches local cluster labels across overlapping windows by maximum timeline overlap
19
+ * to produce session-stable anonymous IDs (`S0`, `S1`, ...).
20
+ */
21
+ export declare class IncrementalDiarizer {
22
+ readonly windowSeconds: number;
23
+ readonly hopSeconds: number;
24
+ private nextGlobalId;
25
+ private lastBatch;
26
+ private committedThrough;
27
+ constructor(windowSeconds?: number, hopSeconds?: number);
28
+ process(provider: DiarizationProvider, pcmWindow: Buffer, windowStart: number): Promise<StitchedDiarizeSegment[]>;
29
+ speakerAt(t: number): string | null;
30
+ }
31
+ /**
32
+ * Maintains the Recall-style speaker timeline (`speakerSpans`), audio energy history,
33
+ * and diarization cluster map (`speakerMap`) to attribute any `[t0, t1]` transcript segment.
34
+ */
35
+ export declare class SpeakerAttributionTimeline {
36
+ readonly diarizer?: IncrementalDiarizer | undefined;
37
+ roster: Participant[];
38
+ localUserId: string;
39
+ localUserName: string;
40
+ currentSpeakerId: string;
41
+ currentSpeakerName: string;
42
+ private lastVisualUpdateMs;
43
+ readonly speakerSpans: SpeakerSpan[];
44
+ readonly audioHistory: {
45
+ t0: number;
46
+ t1: number;
47
+ sysRMS: number;
48
+ micRMS: number;
49
+ micActive: boolean;
50
+ }[];
51
+ readonly speakerMap: Map<string, string>;
52
+ private readonly uiLagCompensationSeconds;
53
+ constructor(diarizer?: IncrementalDiarizer | undefined);
54
+ updateRoster(payload: CaptureRosterPayload): void;
55
+ recordSpeakerActivity(payload: CaptureSpeakerPayload): void;
56
+ recordAudioChunk(chunk: CaptureAudioPayload): void;
57
+ hasSpeechEnergy(t0: number, t1: number): boolean;
58
+ private energyStats;
59
+ bestVisualSpeaker(t0: number, t1: number): {
60
+ id: string;
61
+ name: string;
62
+ } | null;
63
+ applyDiarizationSegments(segments: StitchedDiarizeSegment[], currentAudioSeconds: number): {
64
+ participantId: string;
65
+ name: string;
66
+ t: number;
67
+ }[];
68
+ speakerAt(t0: number, t1: number): {
69
+ id: string;
70
+ name: string;
71
+ };
72
+ }
73
+ export interface MeetingSessionPipelineOptions {
74
+ stt?: STTProvider;
75
+ diarize?: DiarizationProvider;
76
+ transcribeOptions?: TranscribeOptions;
77
+ /** Chunk duration in seconds when using a batch/HTTP STT provider (default: 3.5s). */
78
+ batchChunkSeconds?: number;
79
+ onEvent: (event: EyesEvent) => void;
80
+ }
81
+ /**
82
+ * Connects live `NativeCaptureBridge` events (audio, roster, speaker spans) to any
83
+ * pluggable `STTProvider` (streaming WebSocket OR batch HTTP/callback) and optional `DiarizationProvider`.
84
+ */
85
+ export declare class MeetingSessionPipeline {
86
+ private readonly opts;
87
+ readonly timeline: SpeakerAttributionTimeline;
88
+ private readonly diarizer?;
89
+ private sttStream?;
90
+ private closed;
91
+ private lastConfirmedText;
92
+ private lastConfirmedEnd;
93
+ private lastPartialText;
94
+ private lastPartialT0;
95
+ private lastPartialT1;
96
+ private batchPcmChunks;
97
+ private batchPcmBytes;
98
+ private batchStartT0;
99
+ private batchLatestT1;
100
+ private batchHasSpeech;
101
+ private batchSilenceDuration;
102
+ private batchInFlight;
103
+ private diarizePcmBuffer;
104
+ private diarizeWindowStart;
105
+ private diarizeTimer;
106
+ private diarizeBusy;
107
+ private currentAudioSeconds;
108
+ constructor(opts: MeetingSessionPipelineOptions);
109
+ start(): Promise<void>;
110
+ handleRoster(payload: CaptureRosterPayload): void;
111
+ handleSpeakerActivity(payload: CaptureSpeakerPayload): void;
112
+ handleSpeakerChange(payload: CaptureSpeakerPayload): void;
113
+ handleAudio(chunk: CaptureAudioPayload): void;
114
+ private flushBatchSTTChunk;
115
+ private consumeSTTStream;
116
+ stop(): Promise<void>;
117
+ }
118
+ //# sourceMappingURL=attribution.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"attribution.d.ts","sourceRoot":"","sources":["../src/attribution.ts"],"names":[],"mappings":"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"}