epist 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.
package/README.md ADDED
@@ -0,0 +1,33 @@
1
+ # epist
2
+
3
+ Official JavaScript/TypeScript SDK for the Epist.ai Audio RAG Platform.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install epist
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ```typescript
14
+ import { Epist } from 'epist';
15
+
16
+ const client = new Epist({
17
+ apiKey: 'YOUR_API_KEY',
18
+ // Optional: baseUrl: 'https://api.epist.ai/v1'
19
+ });
20
+
21
+ // 1. Upload Audio
22
+ const upload = await client.uploadFile(fileInputElement.files[0]);
23
+ console.log('Task ID:', upload.id);
24
+
25
+ // 2. Transcribe from URL
26
+ const task = await client.transcribeUrl('https://example.com/audio.mp3');
27
+
28
+ // 3. Search
29
+ const results = await client.search('deployment issues');
30
+ results.forEach(r => {
31
+ console.log(`[${r.score}] ${r.text}`);
32
+ });
33
+ ```
@@ -0,0 +1,62 @@
1
+ export interface EpistConfig {
2
+ apiKey: string;
3
+ baseUrl?: string;
4
+ }
5
+ export interface SearchResult {
6
+ id: string;
7
+ text: string;
8
+ start: number;
9
+ end: number;
10
+ score: number;
11
+ methods: string[];
12
+ }
13
+ export interface AudioStatus {
14
+ id: string;
15
+ status: 'pending' | 'processing' | 'completed' | 'failed';
16
+ title: string;
17
+ created_at: string;
18
+ error?: string;
19
+ }
20
+ export interface TranscriptSegment {
21
+ id: string;
22
+ start: number;
23
+ end: number;
24
+ text: string;
25
+ speaker?: string;
26
+ }
27
+ export interface Transcript {
28
+ id: string;
29
+ text: string;
30
+ segments: TranscriptSegment[];
31
+ }
32
+ export declare class EpistError extends Error {
33
+ statusCode?: number | undefined;
34
+ originalError?: any | undefined;
35
+ constructor(message: string, statusCode?: number | undefined, originalError?: any | undefined);
36
+ }
37
+ export declare class Epist {
38
+ private client;
39
+ constructor(config: EpistConfig);
40
+ private handleError;
41
+ /**
42
+ * Upload a local file.
43
+ * @param file - File object (Browser) or fs.ReadStream (Node.js)
44
+ */
45
+ uploadFile(file: any, preset?: string): Promise<AudioStatus>;
46
+ /**
47
+ * Transcribe audio from a URL
48
+ */
49
+ transcribeUrl(url: string, ragEnabled?: boolean, language?: string, preset?: string, chunkingConfig?: any): Promise<AudioStatus>;
50
+ /**
51
+ * Get status of an audio task
52
+ */
53
+ getStatus(audioId: string): Promise<AudioStatus>;
54
+ /**
55
+ * Get full transcript
56
+ */
57
+ getTranscript(audioId: string): Promise<Transcript>;
58
+ /**
59
+ * Search the knowledge base
60
+ */
61
+ search(query: string, limit?: number): Promise<SearchResult[]>;
62
+ }
@@ -0,0 +1,119 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.Epist = exports.EpistError = void 0;
7
+ const axios_1 = __importDefault(require("axios"));
8
+ class EpistError extends Error {
9
+ constructor(message, statusCode, originalError) {
10
+ super(message);
11
+ this.statusCode = statusCode;
12
+ this.originalError = originalError;
13
+ this.name = 'EpistError';
14
+ }
15
+ }
16
+ exports.EpistError = EpistError;
17
+ class Epist {
18
+ constructor(config) {
19
+ this.client = axios_1.default.create({
20
+ baseURL: config.baseUrl || 'https://epist-api-staging-920152096400.us-central1.run.app/api/v1',
21
+ headers: {
22
+ 'X-API-Key': config.apiKey,
23
+ // Do not set global Content-Type for all requests as it breaks multipart uploads
24
+ },
25
+ });
26
+ }
27
+ handleError(error) {
28
+ var _a, _b, _c;
29
+ if (axios_1.default.isAxiosError(error)) {
30
+ const message = ((_b = (_a = error.response) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.detail) || error.message;
31
+ throw new EpistError(message, (_c = error.response) === null || _c === void 0 ? void 0 : _c.status, error);
32
+ }
33
+ throw new EpistError(error instanceof Error ? error.message : 'Unknown error', undefined, error);
34
+ }
35
+ /**
36
+ * Upload a local file.
37
+ * @param file - File object (Browser) or fs.ReadStream (Node.js)
38
+ */
39
+ async uploadFile(file, preset = 'general') {
40
+ try {
41
+ // In Node 18+ and Browsers, FormData is global.
42
+ const formData = new FormData();
43
+ formData.append('file', file);
44
+ formData.append('preset', preset);
45
+ const response = await this.client.post('/audio/upload', formData, {
46
+ headers: {
47
+ // Axios will set 'Content-Type': 'multipart/form-data; boundary=...' automatically
48
+ }
49
+ });
50
+ return response.data;
51
+ }
52
+ catch (error) {
53
+ this.handleError(error);
54
+ throw error; // unreachable
55
+ }
56
+ }
57
+ /**
58
+ * Transcribe audio from a URL
59
+ */
60
+ async transcribeUrl(url, ragEnabled = true, language = 'en', preset = 'general', chunkingConfig = null) {
61
+ try {
62
+ const response = await this.client.post('/audio/transcribe_url', {
63
+ audio_url: url,
64
+ rag_enabled: ragEnabled,
65
+ language,
66
+ preset,
67
+ chunking_config: chunkingConfig
68
+ });
69
+ return response.data;
70
+ }
71
+ catch (error) {
72
+ this.handleError(error);
73
+ throw error;
74
+ }
75
+ }
76
+ /**
77
+ * Get status of an audio task
78
+ */
79
+ async getStatus(audioId) {
80
+ try {
81
+ const response = await this.client.get(`/audio/${audioId}`);
82
+ return response.data;
83
+ }
84
+ catch (error) {
85
+ this.handleError(error);
86
+ throw error;
87
+ }
88
+ }
89
+ /**
90
+ * Get full transcript
91
+ */
92
+ async getTranscript(audioId) {
93
+ try {
94
+ const response = await this.client.get(`/audio/${audioId}/transcript`);
95
+ return response.data;
96
+ }
97
+ catch (error) {
98
+ this.handleError(error);
99
+ throw error;
100
+ }
101
+ }
102
+ /**
103
+ * Search the knowledge base
104
+ */
105
+ async search(query, limit = 10) {
106
+ try {
107
+ const response = await this.client.post('/search', {
108
+ query,
109
+ limit,
110
+ });
111
+ return response.data;
112
+ }
113
+ catch (error) {
114
+ this.handleError(error);
115
+ throw error;
116
+ }
117
+ }
118
+ }
119
+ exports.Epist = Epist;
@@ -0,0 +1,111 @@
1
+ import axios from 'axios';
2
+ export class EpistError extends Error {
3
+ constructor(message, statusCode, originalError) {
4
+ super(message);
5
+ this.statusCode = statusCode;
6
+ this.originalError = originalError;
7
+ this.name = 'EpistError';
8
+ }
9
+ }
10
+ export class Epist {
11
+ constructor(config) {
12
+ this.client = axios.create({
13
+ baseURL: config.baseUrl || 'https://epist-api-staging-920152096400.us-central1.run.app/api/v1',
14
+ headers: {
15
+ 'X-API-Key': config.apiKey,
16
+ // Do not set global Content-Type for all requests as it breaks multipart uploads
17
+ },
18
+ });
19
+ }
20
+ handleError(error) {
21
+ var _a, _b, _c;
22
+ if (axios.isAxiosError(error)) {
23
+ const message = ((_b = (_a = error.response) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.detail) || error.message;
24
+ throw new EpistError(message, (_c = error.response) === null || _c === void 0 ? void 0 : _c.status, error);
25
+ }
26
+ throw new EpistError(error instanceof Error ? error.message : 'Unknown error', undefined, error);
27
+ }
28
+ /**
29
+ * Upload a local file.
30
+ * @param file - File object (Browser) or fs.ReadStream (Node.js)
31
+ */
32
+ async uploadFile(file, preset = 'general') {
33
+ try {
34
+ // In Node 18+ and Browsers, FormData is global.
35
+ const formData = new FormData();
36
+ formData.append('file', file);
37
+ formData.append('preset', preset);
38
+ const response = await this.client.post('/audio/upload', formData, {
39
+ headers: {
40
+ // Axios will set 'Content-Type': 'multipart/form-data; boundary=...' automatically
41
+ }
42
+ });
43
+ return response.data;
44
+ }
45
+ catch (error) {
46
+ this.handleError(error);
47
+ throw error; // unreachable
48
+ }
49
+ }
50
+ /**
51
+ * Transcribe audio from a URL
52
+ */
53
+ async transcribeUrl(url, ragEnabled = true, language = 'en', preset = 'general', chunkingConfig = null) {
54
+ try {
55
+ const response = await this.client.post('/audio/transcribe_url', {
56
+ audio_url: url,
57
+ rag_enabled: ragEnabled,
58
+ language,
59
+ preset,
60
+ chunking_config: chunkingConfig
61
+ });
62
+ return response.data;
63
+ }
64
+ catch (error) {
65
+ this.handleError(error);
66
+ throw error;
67
+ }
68
+ }
69
+ /**
70
+ * Get status of an audio task
71
+ */
72
+ async getStatus(audioId) {
73
+ try {
74
+ const response = await this.client.get(`/audio/${audioId}`);
75
+ return response.data;
76
+ }
77
+ catch (error) {
78
+ this.handleError(error);
79
+ throw error;
80
+ }
81
+ }
82
+ /**
83
+ * Get full transcript
84
+ */
85
+ async getTranscript(audioId) {
86
+ try {
87
+ const response = await this.client.get(`/audio/${audioId}/transcript`);
88
+ return response.data;
89
+ }
90
+ catch (error) {
91
+ this.handleError(error);
92
+ throw error;
93
+ }
94
+ }
95
+ /**
96
+ * Search the knowledge base
97
+ */
98
+ async search(query, limit = 10) {
99
+ try {
100
+ const response = await this.client.post('/search', {
101
+ query,
102
+ limit,
103
+ });
104
+ return response.data;
105
+ }
106
+ catch (error) {
107
+ this.handleError(error);
108
+ throw error;
109
+ }
110
+ }
111
+ }
package/package.json ADDED
@@ -0,0 +1,33 @@
1
+ {
2
+ "name": "epist",
3
+ "version": "0.1.0",
4
+ "description": "Official JavaScript/TypeScript SDK for Epist.ai",
5
+ "main": "dist/cjs/index.js",
6
+ "module": "dist/esm/index.js",
7
+ "types": "dist/cjs/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./dist/esm/index.js",
11
+ "require": "./dist/cjs/index.js",
12
+ "types": "./dist/cjs/index.d.ts"
13
+ }
14
+ },
15
+ "scripts": {
16
+ "build": "tsc && tsc -p tsconfig.esm.json",
17
+ "prepublishOnly": "npm run build"
18
+ },
19
+ "keywords": [
20
+ "epist",
21
+ "audio",
22
+ "rag",
23
+ "sdk"
24
+ ],
25
+ "author": "Epist Team",
26
+ "license": "MIT",
27
+ "devDependencies": {
28
+ "typescript": "^5.0.0"
29
+ },
30
+ "dependencies": {
31
+ "axios": "^1.6.0"
32
+ }
33
+ }
package/src/index.ts ADDED
@@ -0,0 +1,157 @@
1
+ import axios, { AxiosInstance, AxiosError } from 'axios';
2
+
3
+ export interface EpistConfig {
4
+ apiKey: string;
5
+ baseUrl?: string;
6
+ }
7
+
8
+ export interface SearchResult {
9
+ id: string;
10
+ text: string;
11
+ start: number;
12
+ end: number;
13
+ score: number;
14
+ methods: string[];
15
+ }
16
+
17
+ export interface AudioStatus {
18
+ id: string;
19
+ status: 'pending' | 'processing' | 'completed' | 'failed';
20
+ title: string;
21
+ created_at: string;
22
+ error?: string;
23
+ }
24
+
25
+ export interface TranscriptSegment {
26
+ id: string;
27
+ start: number;
28
+ end: number;
29
+ text: string;
30
+ speaker?: string;
31
+ }
32
+
33
+ export interface Transcript {
34
+ id: string;
35
+ text: string;
36
+ segments: TranscriptSegment[];
37
+ }
38
+
39
+ export class EpistError extends Error {
40
+ constructor(message: string, public statusCode?: number, public originalError?: any) {
41
+ super(message);
42
+ this.name = 'EpistError';
43
+ }
44
+ }
45
+
46
+ export class Epist {
47
+ private client: AxiosInstance;
48
+
49
+ constructor(config: EpistConfig) {
50
+ this.client = axios.create({
51
+ baseURL: config.baseUrl || 'https://epist-api-staging-920152096400.us-central1.run.app/api/v1',
52
+ headers: {
53
+ 'X-API-Key': config.apiKey,
54
+ // Do not set global Content-Type for all requests as it breaks multipart uploads
55
+ },
56
+ });
57
+ }
58
+
59
+ private handleError(error: unknown) {
60
+ if (axios.isAxiosError(error)) {
61
+ const message = error.response?.data?.detail || error.message;
62
+ throw new EpistError(message, error.response?.status, error);
63
+ }
64
+ throw new EpistError(error instanceof Error ? error.message : 'Unknown error', undefined, error);
65
+ }
66
+
67
+ /**
68
+ * Upload a local file.
69
+ * @param file - File object (Browser) or fs.ReadStream (Node.js)
70
+ */
71
+ async uploadFile(file: any, preset: string = 'general'): Promise<AudioStatus> {
72
+ try {
73
+ // In Node 18+ and Browsers, FormData is global.
74
+ const formData = new FormData();
75
+ formData.append('file', file);
76
+ formData.append('preset', preset);
77
+
78
+ const response = await this.client.post('/audio/upload', formData, {
79
+ headers: {
80
+ // Axios will set 'Content-Type': 'multipart/form-data; boundary=...' automatically
81
+ }
82
+ });
83
+ return response.data;
84
+ } catch (error) {
85
+ this.handleError(error);
86
+ throw error; // unreachable
87
+ }
88
+ }
89
+
90
+ /**
91
+ * Transcribe audio from a URL
92
+ */
93
+ async transcribeUrl(
94
+ url: string,
95
+ ragEnabled: boolean = true,
96
+ language: string = 'en',
97
+ preset: string = 'general',
98
+ chunkingConfig: any = null
99
+ ): Promise<AudioStatus> {
100
+ try {
101
+ const response = await this.client.post('/audio/transcribe_url', {
102
+ audio_url: url,
103
+ rag_enabled: ragEnabled,
104
+ language,
105
+ preset,
106
+ chunking_config: chunkingConfig
107
+ });
108
+ return response.data;
109
+ } catch (error) {
110
+ this.handleError(error);
111
+ throw error;
112
+ }
113
+ }
114
+
115
+ /**
116
+ * Get status of an audio task
117
+ */
118
+ async getStatus(audioId: string): Promise<AudioStatus> {
119
+ try {
120
+ const response = await this.client.get(`/audio/${audioId}`);
121
+ return response.data;
122
+ } catch (error) {
123
+ this.handleError(error);
124
+ throw error;
125
+ }
126
+ }
127
+
128
+ /**
129
+ * Get full transcript
130
+ */
131
+ async getTranscript(audioId: string): Promise<Transcript> {
132
+ try {
133
+ const response = await this.client.get(`/audio/${audioId}/transcript`);
134
+ return response.data;
135
+ } catch (error) {
136
+ this.handleError(error);
137
+ throw error;
138
+ }
139
+ }
140
+
141
+ /**
142
+ * Search the knowledge base
143
+ */
144
+ async search(query: string, limit: number = 10): Promise<SearchResult[]> {
145
+ try {
146
+ const response = await this.client.post('/search', {
147
+ query,
148
+ limit,
149
+ });
150
+ return response.data;
151
+ } catch (error) {
152
+ this.handleError(error);
153
+ throw error;
154
+ }
155
+ }
156
+ }
157
+
@@ -0,0 +1,12 @@
1
+ {
2
+ "extends": "./tsconfig.json",
3
+ "compilerOptions": {
4
+ "module": "esnext",
5
+ "moduleResolution": "bundler",
6
+ "outDir": "./dist/esm",
7
+ "declaration": false
8
+ },
9
+ "include": [
10
+ "src/**/*"
11
+ ]
12
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,20 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "es2018",
4
+ "module": "commonjs",
5
+ "lib": [
6
+ "es2018",
7
+ "dom"
8
+ ],
9
+ "declaration": true,
10
+ "outDir": "./dist/cjs",
11
+ "strict": true,
12
+ "moduleResolution": "node",
13
+ "esModuleInterop": true,
14
+ "skipLibCheck": true,
15
+ "forceConsistentCasingInFileNames": true
16
+ },
17
+ "include": [
18
+ "src/**/*"
19
+ ]
20
+ }