whio-api-sdk 1.0.167 → 1.0.169

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.
@@ -1,4 +1,4 @@
1
- import { LoginResponse, LoginCredentials, SDKConfig, User, UpdateUserDto, Organization, TemplateCategory, Template, Team, UserTemplate, TranscriptionSummary, TranscriptionAudioUploadResponse, PasswordChangeResponse, Session, CreateSessionDto, UpdateSessionDto } from './types';
1
+ import { LoginResponse, LoginCredentials, SDKConfig, User, UpdateUserDto, Organization, TemplateCategory, Template, Team, UserTemplate, TranscriptionSummary, TranscriptionAudioUploadResponse, PasswordChangeResponse, Session, CreateSessionDto, UpdateSessionDto, Agent, AudioFile, UpdateAudioFileDto } from './types';
2
2
  export declare class ApiSDK {
3
3
  private baseUrl;
4
4
  private storage;
@@ -89,4 +89,21 @@ export declare class ApiSDK {
89
89
  updateSession(id: string, sessionData: UpdateSessionDto): Promise<Session>;
90
90
  deleteSession(id: string): Promise<void>;
91
91
  setPrimaryTranscriptionSummary(sessionId: string, summaryId: string): Promise<Session>;
92
+ createAgent(name: string): Promise<Agent>;
93
+ getAgents(): Promise<Agent[]>;
94
+ getAgent(id: string): Promise<Agent>;
95
+ updateAgent(id: string, name: string): Promise<Agent>;
96
+ deleteAgent(id: string): Promise<void>;
97
+ addAgentToOrganization(agentId: string, organizationId: string): Promise<void>;
98
+ removeAgentFromOrganization(agentId: string, organizationId: string): Promise<void>;
99
+ uploadAudioFileToSession(sessionId: string, file: File | Blob, fileName?: string): Promise<AudioFile>;
100
+ getMyAudioFiles(): Promise<AudioFile[]>;
101
+ getAllAudioFiles(): Promise<AudioFile[]>;
102
+ getOrganizationAudioFiles(): Promise<AudioFile[]>;
103
+ getAudioFilesBySession(sessionId: string): Promise<AudioFile[]>;
104
+ getAudioFile(id: string): Promise<AudioFile>;
105
+ updateAudioFile(id: string, updates: UpdateAudioFileDto): Promise<AudioFile>;
106
+ deleteAudioFile(id: string): Promise<void>;
107
+ downloadAudioFile(id: string): Promise<Blob>;
108
+ downloadAudioFileAsUrl(id: string): Promise<string>;
92
109
  }
@@ -678,4 +678,118 @@ export class ApiSDK {
678
678
  return this.request(`${urls.sessions}/${sessionId}/primary-summary/${summaryId}`, 'PATCH');
679
679
  });
680
680
  }
681
+ // ======================
682
+ // AGENT METHODS
683
+ // ======================
684
+ createAgent(name) {
685
+ return __awaiter(this, void 0, void 0, function* () {
686
+ const dto = { name };
687
+ return this.request(urls.agents, 'POST', dto);
688
+ });
689
+ }
690
+ getAgents() {
691
+ return __awaiter(this, void 0, void 0, function* () {
692
+ return this.request(urls.agents, 'GET');
693
+ });
694
+ }
695
+ getAgent(id) {
696
+ return __awaiter(this, void 0, void 0, function* () {
697
+ return this.request(`${urls.agents}/${id}`, 'GET');
698
+ });
699
+ }
700
+ updateAgent(id, name) {
701
+ return __awaiter(this, void 0, void 0, function* () {
702
+ const dto = { name };
703
+ return this.request(`${urls.agents}/${id}`, 'PATCH', dto);
704
+ });
705
+ }
706
+ deleteAgent(id) {
707
+ return __awaiter(this, void 0, void 0, function* () {
708
+ yield this.request(`${urls.agents}/${id}`, 'DELETE');
709
+ });
710
+ }
711
+ addAgentToOrganization(agentId, organizationId) {
712
+ return __awaiter(this, void 0, void 0, function* () {
713
+ yield this.request(`${urls.agents}/${agentId}/organizations/${organizationId}`, 'POST');
714
+ });
715
+ }
716
+ removeAgentFromOrganization(agentId, organizationId) {
717
+ return __awaiter(this, void 0, void 0, function* () {
718
+ yield this.request(`${urls.agents}/${agentId}/organizations/${organizationId}`, 'DELETE');
719
+ });
720
+ }
721
+ // ======================
722
+ // AUDIO FILE METHODS
723
+ // ======================
724
+ uploadAudioFileToSession(sessionId, file, fileName) {
725
+ return __awaiter(this, void 0, void 0, function* () {
726
+ const formData = new FormData();
727
+ formData.append('file', file, fileName);
728
+ return this.fileUploadRequest(`${urls.audioFiles}/upload/${sessionId}`, formData);
729
+ });
730
+ }
731
+ getMyAudioFiles() {
732
+ return __awaiter(this, void 0, void 0, function* () {
733
+ return this.request(`${urls.audioFiles}/my-files`, 'GET');
734
+ });
735
+ }
736
+ getAllAudioFiles() {
737
+ return __awaiter(this, void 0, void 0, function* () {
738
+ return this.request(`${urls.audioFiles}/all`, 'GET');
739
+ });
740
+ }
741
+ getOrganizationAudioFiles() {
742
+ return __awaiter(this, void 0, void 0, function* () {
743
+ return this.request(`${urls.audioFiles}/organization`, 'GET');
744
+ });
745
+ }
746
+ getAudioFilesBySession(sessionId) {
747
+ return __awaiter(this, void 0, void 0, function* () {
748
+ return this.request(`${urls.audioFiles}/session/${sessionId}`, 'GET');
749
+ });
750
+ }
751
+ getAudioFile(id) {
752
+ return __awaiter(this, void 0, void 0, function* () {
753
+ return this.request(`${urls.audioFiles}/${id}`, 'GET');
754
+ });
755
+ }
756
+ updateAudioFile(id, updates) {
757
+ return __awaiter(this, void 0, void 0, function* () {
758
+ return this.request(`${urls.audioFiles}/${id}`, 'PATCH', updates);
759
+ });
760
+ }
761
+ deleteAudioFile(id) {
762
+ return __awaiter(this, void 0, void 0, function* () {
763
+ yield this.request(`${urls.audioFiles}/${id}`, 'DELETE');
764
+ });
765
+ }
766
+ downloadAudioFile(id) {
767
+ return __awaiter(this, void 0, void 0, function* () {
768
+ // For file downloads, we need a different approach than JSON requests
769
+ const url = `${this.baseUrl}${urls.audioFiles}/${id}/download`;
770
+ // Get token first
771
+ yield this.getToken();
772
+ const defaultHeaders = {
773
+ 'ngrok-skip-browser-warning': 'true'
774
+ };
775
+ if (this.accessToken) {
776
+ defaultHeaders['Authorization'] = `Bearer ${this.accessToken}`;
777
+ }
778
+ const response = yield fetch(url, {
779
+ method: 'GET',
780
+ headers: defaultHeaders,
781
+ });
782
+ if (!response.ok) {
783
+ const errorData = yield response.json().catch(() => ({}));
784
+ throw new Error(errorData.message || `Download failed with status ${response.status}`);
785
+ }
786
+ return response.blob();
787
+ });
788
+ }
789
+ downloadAudioFileAsUrl(id) {
790
+ return __awaiter(this, void 0, void 0, function* () {
791
+ const blob = yield this.downloadAudioFile(id);
792
+ return URL.createObjectURL(blob);
793
+ });
794
+ }
681
795
  }
@@ -31,6 +31,7 @@ export interface Organization {
31
31
  updatedAt: string;
32
32
  users?: User[];
33
33
  roles?: OrganizationRole[];
34
+ agents?: AgentOrganization[];
34
35
  }
35
36
  export interface User {
36
37
  id: string;
@@ -306,3 +307,59 @@ export interface UpdateSessionDto {
306
307
  sessionName?: string;
307
308
  primaryTranscriptionSummaryId?: string;
308
309
  }
310
+ export interface Agent {
311
+ id: string;
312
+ name: string;
313
+ createdAt: string;
314
+ updatedAt: string;
315
+ organizations?: AgentOrganization[];
316
+ }
317
+ export interface AgentOrganization {
318
+ agentId: string;
319
+ organizationId: string;
320
+ createdAt: string;
321
+ agent?: Agent;
322
+ organization?: Organization;
323
+ }
324
+ export interface CreateAgentDto {
325
+ name: string;
326
+ }
327
+ export interface UpdateAgentDto {
328
+ name?: string;
329
+ }
330
+ export declare enum AudioFileStatus {
331
+ UPLOADED = "UPLOADED",
332
+ PROCESSING = "PROCESSING",
333
+ TRANSCRIBED = "TRANSCRIBED",
334
+ FAILED = "FAILED"
335
+ }
336
+ export interface AudioFile {
337
+ id: string;
338
+ originalName: string;
339
+ fileName: string;
340
+ filePath: string;
341
+ fileSize: number;
342
+ mimeType: string;
343
+ uploadId?: string;
344
+ transcriptionUrl?: string;
345
+ status: AudioFileStatus;
346
+ createdAt: string;
347
+ updatedAt: string;
348
+ sessionId: string;
349
+ userId: string;
350
+ session?: Session;
351
+ user?: User;
352
+ }
353
+ export interface CreateAudioFileDto {
354
+ originalName: string;
355
+ fileName: string;
356
+ filePath: string;
357
+ fileSize: number;
358
+ mimeType: string;
359
+ uploadId?: string;
360
+ sessionId: string;
361
+ }
362
+ export interface UpdateAudioFileDto {
363
+ transcriptionUrl?: string;
364
+ status?: AudioFileStatus;
365
+ }
@@ -13,3 +13,11 @@ export var RoleType;
13
13
  RoleType["TRIAL"] = "TRIAL";
14
14
  RoleType["PAID"] = "PAID";
15
15
  })(RoleType || (RoleType = {}));
16
+ // Audio File types
17
+ export var AudioFileStatus;
18
+ (function (AudioFileStatus) {
19
+ AudioFileStatus["UPLOADED"] = "UPLOADED";
20
+ AudioFileStatus["PROCESSING"] = "PROCESSING";
21
+ AudioFileStatus["TRANSCRIBED"] = "TRANSCRIBED";
22
+ AudioFileStatus["FAILED"] = "FAILED";
23
+ })(AudioFileStatus || (AudioFileStatus = {}));
@@ -25,5 +25,7 @@ declare const urls: {
25
25
  roles: string;
26
26
  userRoles: string;
27
27
  sessions: string;
28
+ agents: string;
29
+ audioFiles: string;
28
30
  };
29
31
  export default urls;
@@ -33,5 +33,9 @@ const urls = {
33
33
  userRoles: '/user-roles',
34
34
  // Sessions
35
35
  sessions: '/sessions',
36
+ // Agents
37
+ agents: '/agents',
38
+ // Audio Files
39
+ audioFiles: '/audio-files',
36
40
  };
37
41
  export default urls;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "whio-api-sdk",
3
- "version": "1.0.167",
3
+ "version": "1.0.169",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "type": "module",
package/src/sdk/sdk.ts CHANGED
@@ -37,6 +37,13 @@ import {
37
37
  Session,
38
38
  CreateSessionDto,
39
39
  UpdateSessionDto,
40
+ Agent,
41
+ CreateAgentDto,
42
+ UpdateAgentDto,
43
+ AudioFile,
44
+ AudioFileStatus,
45
+ CreateAudioFileDto,
46
+ UpdateAudioFileDto,
40
47
  } from './types';
41
48
  import urls from './urls';
42
49
  import { jwtDecode } from 'jwt-decode';
@@ -747,4 +754,112 @@ export class ApiSDK {
747
754
  return this.request<Session>(`${urls.sessions}/${sessionId}/primary-summary/${summaryId}`, 'PATCH');
748
755
  }
749
756
 
757
+ // ======================
758
+ // AGENT METHODS
759
+ // ======================
760
+
761
+ public async createAgent(name: string): Promise<Agent> {
762
+ const dto: CreateAgentDto = { name };
763
+ return this.request<Agent>(urls.agents, 'POST', dto);
764
+ }
765
+
766
+ public async getAgents(): Promise<Agent[]> {
767
+ return this.request<Agent[]>(urls.agents, 'GET');
768
+ }
769
+
770
+ public async getAgent(id: string): Promise<Agent> {
771
+ return this.request<Agent>(`${urls.agents}/${id}`, 'GET');
772
+ }
773
+
774
+ public async updateAgent(id: string, name: string): Promise<Agent> {
775
+ const dto: UpdateAgentDto = { name };
776
+ return this.request<Agent>(`${urls.agents}/${id}`, 'PATCH', dto);
777
+ }
778
+
779
+ public async deleteAgent(id: string): Promise<void> {
780
+ await this.request(`${urls.agents}/${id}`, 'DELETE');
781
+ }
782
+
783
+ public async addAgentToOrganization(agentId: string, organizationId: string): Promise<void> {
784
+ await this.request(`${urls.agents}/${agentId}/organizations/${organizationId}`, 'POST');
785
+ }
786
+
787
+ public async removeAgentFromOrganization(agentId: string, organizationId: string): Promise<void> {
788
+ await this.request(`${urls.agents}/${agentId}/organizations/${organizationId}`, 'DELETE');
789
+ }
790
+
791
+ // ======================
792
+ // AUDIO FILE METHODS
793
+ // ======================
794
+
795
+ public async uploadAudioFileToSession(sessionId: string, file: File | Blob, fileName?: string): Promise<AudioFile> {
796
+ const formData = new FormData();
797
+ formData.append('file', file, fileName);
798
+
799
+ return this.fileUploadRequest<AudioFile>(`${urls.audioFiles}/upload/${sessionId}`, formData);
800
+ }
801
+
802
+ public async getMyAudioFiles(): Promise<AudioFile[]> {
803
+ return this.request<AudioFile[]>(`${urls.audioFiles}/my-files`, 'GET');
804
+ }
805
+
806
+ public async getAllAudioFiles(): Promise<AudioFile[]> {
807
+ return this.request<AudioFile[]>(`${urls.audioFiles}/all`, 'GET');
808
+ }
809
+
810
+ public async getOrganizationAudioFiles(): Promise<AudioFile[]> {
811
+ return this.request<AudioFile[]>(`${urls.audioFiles}/organization`, 'GET');
812
+ }
813
+
814
+ public async getAudioFilesBySession(sessionId: string): Promise<AudioFile[]> {
815
+ return this.request<AudioFile[]>(`${urls.audioFiles}/session/${sessionId}`, 'GET');
816
+ }
817
+
818
+ public async getAudioFile(id: string): Promise<AudioFile> {
819
+ return this.request<AudioFile>(`${urls.audioFiles}/${id}`, 'GET');
820
+ }
821
+
822
+ public async updateAudioFile(id: string, updates: UpdateAudioFileDto): Promise<AudioFile> {
823
+ return this.request<AudioFile>(`${urls.audioFiles}/${id}`, 'PATCH', updates);
824
+ }
825
+
826
+ public async deleteAudioFile(id: string): Promise<void> {
827
+ await this.request(`${urls.audioFiles}/${id}`, 'DELETE');
828
+ }
829
+
830
+ public async downloadAudioFile(id: string): Promise<Blob> {
831
+ // For file downloads, we need a different approach than JSON requests
832
+ const url = `${this.baseUrl}${urls.audioFiles}/${id}/download`;
833
+
834
+ // Get token first
835
+ await this.getToken();
836
+
837
+ const defaultHeaders: Record<string, string> = {
838
+ 'ngrok-skip-browser-warning': 'true'
839
+ };
840
+
841
+ if (this.accessToken) {
842
+ defaultHeaders['Authorization'] = `Bearer ${this.accessToken}`;
843
+ }
844
+
845
+ const response = await fetch(url, {
846
+ method: 'GET',
847
+ headers: defaultHeaders,
848
+ });
849
+
850
+ if (!response.ok) {
851
+ const errorData = await response.json().catch(() => ({}));
852
+ throw new Error(
853
+ errorData.message || `Download failed with status ${response.status}`
854
+ );
855
+ }
856
+
857
+ return response.blob();
858
+ }
859
+
860
+ public async downloadAudioFileAsUrl(id: string): Promise<string> {
861
+ const blob = await this.downloadAudioFile(id);
862
+ return URL.createObjectURL(blob);
863
+ }
864
+
750
865
  }
package/src/sdk/types.ts CHANGED
@@ -43,6 +43,7 @@ export interface Organization {
43
43
 
44
44
  users?: User[];
45
45
  roles?: OrganizationRole[];
46
+ agents?: AgentOrganization[];
46
47
  }
47
48
 
48
49
  // User type
@@ -387,3 +388,75 @@ export interface UpdateSessionDto {
387
388
  sessionName?: string;
388
389
  primaryTranscriptionSummaryId?: string;
389
390
  }
391
+
392
+ // Agent types
393
+ export interface Agent {
394
+ id: string;
395
+ name: string;
396
+ createdAt: string;
397
+ updatedAt: string;
398
+ organizations?: AgentOrganization[];
399
+ }
400
+
401
+ // Agent Organization association
402
+ export interface AgentOrganization {
403
+ agentId: string;
404
+ organizationId: string;
405
+ createdAt: string;
406
+ agent?: Agent;
407
+ organization?: Organization;
408
+ }
409
+
410
+ // Agent DTOs
411
+ export interface CreateAgentDto {
412
+ name: string;
413
+ }
414
+
415
+ export interface UpdateAgentDto {
416
+ name?: string;
417
+ }
418
+
419
+ // Audio File types
420
+ export enum AudioFileStatus {
421
+ UPLOADED = 'UPLOADED',
422
+ PROCESSING = 'PROCESSING',
423
+ TRANSCRIBED = 'TRANSCRIBED',
424
+ FAILED = 'FAILED',
425
+ }
426
+
427
+ export interface AudioFile {
428
+ id: string;
429
+ originalName: string;
430
+ fileName: string;
431
+ filePath: string;
432
+ fileSize: number;
433
+ mimeType: string;
434
+ uploadId?: string;
435
+ transcriptionUrl?: string;
436
+ status: AudioFileStatus;
437
+ createdAt: string;
438
+ updatedAt: string;
439
+ sessionId: string;
440
+ userId: string;
441
+
442
+ // Relationships (populated by API)
443
+ session?: Session;
444
+ user?: User;
445
+ }
446
+
447
+ // Audio File DTOs
448
+ export interface CreateAudioFileDto {
449
+ originalName: string;
450
+ fileName: string;
451
+ filePath: string;
452
+ fileSize: number;
453
+ mimeType: string;
454
+ uploadId?: string;
455
+ sessionId: string;
456
+ // userId will be auto-injected by API
457
+ }
458
+
459
+ export interface UpdateAudioFileDto {
460
+ transcriptionUrl?: string;
461
+ status?: AudioFileStatus;
462
+ }
package/src/sdk/urls.ts CHANGED
@@ -40,6 +40,12 @@ const urls = {
40
40
 
41
41
  // Sessions
42
42
  sessions: '/sessions',
43
+
44
+ // Agents
45
+ agents: '/agents',
46
+
47
+ // Audio Files
48
+ audioFiles: '/audio-files',
43
49
  }
44
50
 
45
51
  export default urls;
@@ -0,0 +1,92 @@
1
+ // Test audio files functionality
2
+ import { ApiSDK, AudioFileStatus } from './dist/index.js';
3
+
4
+ const sdk = new ApiSDK({
5
+ baseUrl: 'http://localhost:3000/api'
6
+ });
7
+
8
+ async function testAudioFiles() {
9
+ try {
10
+ // Login
11
+ const loginResponse = await sdk.login({
12
+ email: 'rimu.boddy@make.nz',
13
+ password: 'cbr400rr'
14
+ });
15
+ console.log('✅ Login successful');
16
+
17
+ // Get user sessions to find a session for audio upload
18
+ const sessions = await sdk.getSessions();
19
+ if (sessions.length === 0) {
20
+ console.log('❌ No sessions found. Create a session first.');
21
+ return;
22
+ }
23
+ const sessionId = sessions[0].id;
24
+ console.log('✅ Found session:', sessionId);
25
+
26
+ // Create a mock audio file (small MP3-like buffer)
27
+ const mockAudioData = new Uint8Array([
28
+ // Minimal MP3 header
29
+ 0x49, 0x44, 0x33, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09,
30
+ // Some fake MP3 data
31
+ 0x54, 0x58, 0x58, 0x58, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00,
32
+ 0x03, 0x74, 0x65, 0x73, 0x74, 0x20, 0x61, 0x75, 0x64, 0x69,
33
+ 0x6F, 0x20, 0x64, 0x61, 0x74, 0x61
34
+ ]);
35
+
36
+ const audioBlob = new Blob([mockAudioData], { type: 'audio/mpeg' });
37
+
38
+ // Test upload audio file
39
+ console.log('🔄 Testing audio file upload...');
40
+ const uploadedFile = await sdk.uploadAudioFileToSession(sessionId, audioBlob, 'test-audio.mp3');
41
+ console.log('✅ Audio file uploaded:', uploadedFile.id);
42
+ console.log(' - Original name:', uploadedFile.originalName);
43
+ console.log(' - Status:', uploadedFile.status);
44
+ console.log(' - File size:', uploadedFile.fileSize, 'bytes');
45
+
46
+ // Test get my audio files
47
+ console.log('🔄 Testing get my audio files...');
48
+ const myFiles = await sdk.getMyAudioFiles();
49
+ console.log('✅ Found', myFiles.length, 'audio files');
50
+
51
+ // Test get audio file details
52
+ console.log('🔄 Testing get audio file details...');
53
+ const fileDetails = await sdk.getAudioFile(uploadedFile.id);
54
+ console.log('✅ Audio file details:', fileDetails.originalName);
55
+
56
+ // Test get audio files by session
57
+ console.log('🔄 Testing get audio files by session...');
58
+ const sessionFiles = await sdk.getAudioFilesBySession(sessionId);
59
+ console.log('✅ Found', sessionFiles.length, 'audio files for session');
60
+
61
+ // Test update audio file
62
+ console.log('🔄 Testing update audio file...');
63
+ const updatedFile = await sdk.updateAudioFile(uploadedFile.id, {
64
+ status: AudioFileStatus.TRANSCRIBED,
65
+ transcriptionUrl: 'https://example.com/transcription'
66
+ });
67
+ console.log('✅ Audio file updated. New status:', updatedFile.status);
68
+
69
+ // Test download audio file
70
+ console.log('🔄 Testing download audio file...');
71
+ const downloadedBlob = await sdk.downloadAudioFile(uploadedFile.id);
72
+ console.log('✅ Audio file downloaded. Size:', downloadedBlob.size, 'bytes');
73
+
74
+ // Test download as URL
75
+ console.log('🔄 Testing download as URL...');
76
+ const downloadUrl = await sdk.downloadAudioFileAsUrl(uploadedFile.id);
77
+ console.log('✅ Audio file URL created:', downloadUrl.substring(0, 50) + '...');
78
+
79
+ // Clean up - delete the test file
80
+ console.log('🔄 Cleaning up - deleting test file...');
81
+ await sdk.deleteAudioFile(uploadedFile.id);
82
+ console.log('✅ Test file deleted');
83
+
84
+ console.log('\n🎉 All audio file SDK tests passed!');
85
+
86
+ } catch (error) {
87
+ console.error('❌ Test failed:', error.message);
88
+ console.error('Error details:', error);
89
+ }
90
+ }
91
+
92
+ testAudioFiles();