skydoc-ambient-scribe-sdk
v1.0.1
Published
Clinical voice-to-text SDK for EMR integration with offline-first architecture
Maintainers
Readme
Ambient Scribe SDK
Clinical voice-to-text SDK for EMR integration with offline-first architecture and automatic SOAP note generation.
✨ Features
- ✅ Offline-first - IndexedDB persistence prevents data loss
- ✅ Background upload - Web Workers keep UI responsive
- ✅ Real-time audio capture - AudioWorklet for non-blocking processing
- ✅ Automatic SOAP notes - Powered by Google Gemini 2.0
- ✅ Framework-agnostic - Works with Angular, React, Vue, vanilla JS
- ✅ TypeScript support - Full type definitions included
- ✅ Production-ready - Error handling, retries, diagnostics
📦 Installation
npm install @your-org/ambient-scribe-sdk🚀 Quick Start
import { AmbientScribe } from '@your-org/ambient-scribe-sdk';
// 1. Initialize SDK
const scribe = new AmbientScribe(
{
backendUrl: 'https://your-backend-url.run.app',
debug: false,
pollingIntervalMs: 2000
},
'/assets/worker.mjs' // Path to worker file
);
// 2. Set up event listeners
scribe.on('recordingStarted', (data) => {
console.log('Recording started:', data.encounterId);
});
scribe.on('noteGenerated', (soapNote) => {
console.log('SOAP Note received:', soapNote);
// Fill your EMR form fields here
});
scribe.on('error', (error) => {
console.error('Error:', error.message);
});
// 3. Start recording
const encounterId = 'encounter-' + Date.now();
await scribe.startRecording(encounterId);
// 4. Stop recording (triggers SOAP note generation)
await scribe.stopRecording();🔧 Configuration
interface ScribeConfig {
backendUrl: string; // Required: Your backend API URL
audioWorkletPath?: string; // Optional: Path to audio-processor.js
debug?: boolean; // Optional: Enable debug logging (default: false)
pollingIntervalMs?: number; // Optional: Status polling interval (default: 2000ms)
maxChunkSizeMB?: number; // Optional: Max chunk size (default: 2MB)
}📋 Events
The SDK emits the following events:
| Event | Payload | Description |
|-------|---------|-------------|
| ready | null | SDK initialized and ready |
| recordingStarted | { encounterId: string } | Recording has started |
| recordingStopped | { encounterId: string } | Recording has stopped |
| chunkUploaded | { sequenceIndex: number, size: number } | Audio chunk uploaded |
| processingStarted | { encounterId: string } | Backend processing started |
| noteGenerated | SoapNoteResponse | SOAP note is ready |
| error | { message: string, code?: string } | Error occurred |
| info | { message: string } | Informational message |
🏥 SOAP Note Format
interface SoapNoteResponse {
encounterId: string;
status: 'COMPLETED';
generatedAt: string;
documentation: {
subjective: {
chiefComplaint: string;
historyOfPresentIllness: string;
reviewOfSystems: object;
};
objective: {
vitalSigns: object;
physicalExamination: object;
};
assessment: {
diagnoses: string[];
differentialDiagnoses: string[];
};
plan: {
medications: Array<{name: string, dosage: string}>;
procedures: string[];
followUp: string;
patientEducation: string;
};
};
metadata: {
processingTimeMs: number;
wordCount: number;
};
}🎯 Angular Integration Example
import { Injectable } from '@angular/core';
import { AmbientScribe } from '@your-org/ambient-scribe-sdk';
@Injectable({ providedIn: 'root' })
export class ScribeService {
private scribe: AmbientScribe;
constructor() {
this.scribe = new AmbientScribe(
{
backendUrl: 'https://your-backend-url.run.app'
},
'/assets/worker.mjs'
);
this.setupListeners();
}
setupListeners() {
this.scribe.on('noteGenerated', (soap) => {
// Fill your EMR form fields
this.populateEMRForm(soap);
});
this.scribe.on('error', (error) => {
// Show error to user
this.showError(error.message);
});
}
startEncounter(patientId: string) {
const encounterId = `enc-${patientId}-${Date.now()}`;
return this.scribe.startRecording(encounterId);
}
endEncounter() {
return this.scribe.stopRecording();
}
private populateEMRForm(soap: any) {
// Map SOAP note to your EMR fields
this.chiefComplaint = soap.documentation.subjective.chiefComplaint;
this.diagnosis = soap.documentation.assessment.diagnoses[0];
// ... etc
}
}📁 Required Files
After installation, copy these files to your Angular src/assets/ folder:
# From node_modules to your assets folder
cp node_modules/@your-org/ambient-scribe-sdk/dist/audio-processor.js src/assets/
cp node_modules/@your-org/ambient-scribe-sdk/dist/worker/worker.mjs src/assets/🛠️ Development
# Clone repository
git clone https://github.com/your-org/ict-sdk
# Install dependencies
cd ict-frontend
npm install
# Build
npm run build
# Test
python3 -m http.server 8080
# Open: http://localhost:8080/test/e2e-test.html📚 API Reference
AmbientScribe Class
Constructor
constructor(config: ScribeConfig, workerUrl: string)Methods
startRecording(encounterId: string): Promise
- Start recording audio for an encounter
- Requests microphone permission
- Returns: Promise that resolves when recording starts
stopRecording(): Promise
- Stop recording and trigger SOAP note generation
- Uploads final chunk
- Returns: Promise that resolves to true when stopped
on(event: string, callback: (data: any) => void): void
- Subscribe to SDK events
- See Events section for available events
off(event: string, callback: (data: any) => void): void
- Unsubscribe from SDK events
🔍 Error Codes
| Code | Description | Action |
|------|-------------|--------|
| MICROPHONE_NOT_FOUND | No microphone detected | Check system settings |
| PERMISSION_DENIED | User denied microphone access | Allow in browser settings |
| MICROPHONE_IN_USE | Already used by another app | Close other apps |
| NO_AUDIO_INPUT | No sound detected | Check microphone connection |
| SILENCE_DETECTED | Only silence detected | Speak louder |
| NETWORK_ERROR | Upload failed | Check network connection |
🧪 Testing
See test/e2e-test.html for a complete working example.
📖 Documentation
- Deployment Guide: See
DEPLOYMENT.mdin backend - API Documentation: See above
- Integration Examples: See
examples/folder
🤝 Support
For issues or questions:
- GitHub Issues: https://github.com/your-org/ict-sdk/issues
- Email: [email protected]
📄 License
MIT License - see LICENSE file for details
🏥 Healthcare Compliance
This SDK is designed for use with HIPAA-compliant backends. Audio data is:
- Encrypted in transit (HTTPS)
- Stored in HIPAA-compliant cloud storage (GCS)
- Processed by HIPAA-compliant infrastructure (Cloud Run)
Note: Ensure your backend is properly configured with a Business Associate Agreement (BAA) from Google Cloud.
