@loonylabs/tti-middleware 1.0.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/.env.example +45 -0
- package/LICENSE +21 -0
- package/README.md +518 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +18 -0
- package/dist/middleware/services/tti/index.d.ts +2 -0
- package/dist/middleware/services/tti/index.js +18 -0
- package/dist/middleware/services/tti/providers/base-tti-provider.d.ts +98 -0
- package/dist/middleware/services/tti/providers/base-tti-provider.js +306 -0
- package/dist/middleware/services/tti/providers/edenai-provider.d.ts +28 -0
- package/dist/middleware/services/tti/providers/edenai-provider.js +181 -0
- package/dist/middleware/services/tti/providers/google-cloud-provider.d.ts +60 -0
- package/dist/middleware/services/tti/providers/google-cloud-provider.js +473 -0
- package/dist/middleware/services/tti/providers/index.d.ts +4 -0
- package/dist/middleware/services/tti/providers/index.js +22 -0
- package/dist/middleware/services/tti/providers/ionos-provider.d.ts +26 -0
- package/dist/middleware/services/tti/providers/ionos-provider.js +134 -0
- package/dist/middleware/services/tti/tti.service.d.ts +70 -0
- package/dist/middleware/services/tti/tti.service.js +162 -0
- package/dist/middleware/types/index.d.ts +196 -0
- package/dist/middleware/types/index.js +37 -0
- package/package.json +90 -0
package/.env.example
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# ============================================================
|
|
2
|
+
# TTI Middleware Configuration
|
|
3
|
+
# ============================================================
|
|
4
|
+
|
|
5
|
+
# Default TTI Provider (optional)
|
|
6
|
+
# Options: google-cloud, edenai, ionos
|
|
7
|
+
TTI_DEFAULT_PROVIDER=google-cloud
|
|
8
|
+
|
|
9
|
+
# ============================================================
|
|
10
|
+
# Testing
|
|
11
|
+
# ============================================================
|
|
12
|
+
# Enable integration tests (makes real API calls, costs money)
|
|
13
|
+
# TTI_INTEGRATION_TESTS=true
|
|
14
|
+
|
|
15
|
+
# ============================================================
|
|
16
|
+
# Google Cloud (Vertex AI) - RECOMMENDED FOR EU/GDPR
|
|
17
|
+
# ============================================================
|
|
18
|
+
# DPA: https://cloud.google.com/terms/data-processing-addendum
|
|
19
|
+
# Models: imagen-3, gemini-flash-image (character consistency)
|
|
20
|
+
|
|
21
|
+
# Project ID (required)
|
|
22
|
+
GOOGLE_CLOUD_PROJECT=your-google-cloud-project-id
|
|
23
|
+
|
|
24
|
+
# Service Account JSON file (required)
|
|
25
|
+
GOOGLE_APPLICATION_CREDENTIALS=./service-account.json
|
|
26
|
+
|
|
27
|
+
# Region (optional, default: europe-west4)
|
|
28
|
+
# EU regions: europe-west1, europe-west4 (recommended), europe-north1
|
|
29
|
+
# Note: gemini-flash-image is NOT available in europe-west3 (Frankfurt)!
|
|
30
|
+
GOOGLE_CLOUD_REGION=europe-west4
|
|
31
|
+
|
|
32
|
+
# ============================================================
|
|
33
|
+
# Eden AI
|
|
34
|
+
# ============================================================
|
|
35
|
+
# Aggregator with multiple underlying providers (OpenAI, Stability AI, etc.)
|
|
36
|
+
|
|
37
|
+
EDENAI_API_KEY=your_edenai_key_here
|
|
38
|
+
|
|
39
|
+
# ============================================================
|
|
40
|
+
# IONOS Cloud
|
|
41
|
+
# ============================================================
|
|
42
|
+
# German cloud provider with EU data centers
|
|
43
|
+
|
|
44
|
+
IONOS_API_KEY=your_ionos_key_here
|
|
45
|
+
IONOS_API_URL=https://api.ionos.cloud/ai/v1
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 LoonyLabs
|
|
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
ADDED
|
@@ -0,0 +1,518 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+
# TTI Middleware
|
|
4
|
+
|
|
5
|
+
*Provider-agnostic Text-to-Image middleware with **GDPR compliance** and **character consistency** support. Currently supports Google Cloud (Imagen 3, Gemini Flash Image), Eden AI, and IONOS. Features EU data residency via Vertex AI, automatic region fallback, retry logic, and comprehensive error handling.*
|
|
6
|
+
|
|
7
|
+
<!-- Horizontal Badge Navigation Bar -->
|
|
8
|
+
[](https://www.npmjs.com/package/@loonylabs/tti-middleware)
|
|
9
|
+
[](https://www.npmjs.com/package/@loonylabs/tti-middleware)
|
|
10
|
+
[](#-features)
|
|
11
|
+
[](#-prerequisites)
|
|
12
|
+
[](#-license)
|
|
13
|
+
[](https://github.com/loonylabs-dev/tti-middleware)
|
|
14
|
+
|
|
15
|
+
</div>
|
|
16
|
+
|
|
17
|
+
<!-- Table of Contents -->
|
|
18
|
+
<details>
|
|
19
|
+
<summary><strong>Table of Contents</strong></summary>
|
|
20
|
+
|
|
21
|
+
- [Features](#-features)
|
|
22
|
+
- [Quick Start](#-quick-start)
|
|
23
|
+
- [Prerequisites](#-prerequisites)
|
|
24
|
+
- [Configuration](#%EF%B8%8F-configuration)
|
|
25
|
+
- [Providers & Models](#-providers--models)
|
|
26
|
+
- [Character Consistency](#-character-consistency)
|
|
27
|
+
- [GDPR / Compliance](#-gdpr--compliance)
|
|
28
|
+
- [API Reference](#-api-reference)
|
|
29
|
+
- [Advanced Features](#-advanced-features)
|
|
30
|
+
- [Testing](#-testing)
|
|
31
|
+
- [Documentation](#-documentation)
|
|
32
|
+
- [Contributing](#-contributing)
|
|
33
|
+
- [License](#-license)
|
|
34
|
+
- [Links](#-links)
|
|
35
|
+
|
|
36
|
+
</details>
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## Features
|
|
41
|
+
|
|
42
|
+
- **Multi-Provider Architecture**: Unified API for all TTI providers
|
|
43
|
+
- **Google Cloud** (Recommended): Imagen 3 & Gemini Flash Image with EU data residency
|
|
44
|
+
- **Eden AI**: Aggregator with access to OpenAI, Stability AI, Replicate (experimental)
|
|
45
|
+
- **IONOS**: German cloud provider with OpenAI-compatible API (experimental)
|
|
46
|
+
- **Character Consistency**: Generate consistent characters across multiple images (perfect for children's book illustrations)
|
|
47
|
+
- **GDPR/DSGVO Compliance**: Built-in EU region support with automatic fallback
|
|
48
|
+
- **Retry Logic**: Automatic retry for rate limits (429) with configurable backoff
|
|
49
|
+
- **TypeScript First**: Full type safety with comprehensive interfaces
|
|
50
|
+
- **Logging Control**: Configurable log levels via environment or API
|
|
51
|
+
- **Error Handling**: Typed error classes for precise error handling
|
|
52
|
+
|
|
53
|
+
## Quick Start
|
|
54
|
+
|
|
55
|
+
### Installation
|
|
56
|
+
|
|
57
|
+
Install from npm:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
npm install @loonylabs/tti-middleware
|
|
61
|
+
|
|
62
|
+
# For Google Cloud provider (recommended):
|
|
63
|
+
npm install @google-cloud/aiplatform @google/genai
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Or install directly from GitHub:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
npm install github:loonylabs-dev/tti-middleware
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Basic Usage
|
|
73
|
+
|
|
74
|
+
```typescript
|
|
75
|
+
import { TTIService, GoogleCloudTTIProvider, TTIProvider } from '@loonylabs/tti-middleware';
|
|
76
|
+
|
|
77
|
+
// Create service and register provider
|
|
78
|
+
const service = new TTIService();
|
|
79
|
+
service.registerProvider(new GoogleCloudTTIProvider({
|
|
80
|
+
projectId: process.env.GOOGLE_CLOUD_PROJECT,
|
|
81
|
+
region: 'europe-west4', // EU region for GDPR
|
|
82
|
+
}));
|
|
83
|
+
|
|
84
|
+
// Generate an image
|
|
85
|
+
const result = await service.generate({
|
|
86
|
+
prompt: 'A futuristic city with flying cars, cyberpunk style',
|
|
87
|
+
model: 'imagen-3',
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
console.log('Image generated:', result.images[0].base64?.substring(0, 50) + '...');
|
|
91
|
+
console.log('Duration:', result.metadata.duration, 'ms');
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
<details>
|
|
95
|
+
<summary><strong>Using Character Consistency</strong></summary>
|
|
96
|
+
|
|
97
|
+
Generate consistent characters across multiple images:
|
|
98
|
+
|
|
99
|
+
```typescript
|
|
100
|
+
// 1. Create the initial character
|
|
101
|
+
const character = await service.generate({
|
|
102
|
+
prompt: 'A cute cartoon bear with a red hat and blue scarf, watercolor style',
|
|
103
|
+
model: 'gemini-flash-image', // Only this model supports character consistency!
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
// 2. Generate new scenes with the same character
|
|
107
|
+
const scene = await service.generate({
|
|
108
|
+
prompt: 'dancing happily in the rain, jumping in puddles',
|
|
109
|
+
model: 'gemini-flash-image',
|
|
110
|
+
referenceImages: [{
|
|
111
|
+
base64: character.images[0].base64!,
|
|
112
|
+
mimeType: 'image/png',
|
|
113
|
+
}],
|
|
114
|
+
subjectDescription: 'cute cartoon bear with red hat and blue scarf',
|
|
115
|
+
});
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
**Important:** Character consistency is only supported by `gemini-flash-image` model!
|
|
119
|
+
|
|
120
|
+
</details>
|
|
121
|
+
|
|
122
|
+
<details>
|
|
123
|
+
<summary><strong>Switching Providers</strong></summary>
|
|
124
|
+
|
|
125
|
+
```typescript
|
|
126
|
+
// Use Google Cloud (recommended for EU)
|
|
127
|
+
const googleResult = await service.generate({
|
|
128
|
+
prompt: 'A mountain landscape',
|
|
129
|
+
model: 'imagen-3',
|
|
130
|
+
}, TTIProvider.GOOGLE_CLOUD);
|
|
131
|
+
|
|
132
|
+
// Use Eden AI (experimental)
|
|
133
|
+
const edenResult = await service.generate({
|
|
134
|
+
prompt: 'A mountain landscape',
|
|
135
|
+
model: 'openai', // Uses DALL-E via Eden AI
|
|
136
|
+
}, TTIProvider.EDENAI);
|
|
137
|
+
|
|
138
|
+
// Use IONOS (experimental)
|
|
139
|
+
const ionosResult = await service.generate({
|
|
140
|
+
prompt: 'A mountain landscape',
|
|
141
|
+
}, TTIProvider.IONOS);
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
</details>
|
|
145
|
+
|
|
146
|
+
## Prerequisites
|
|
147
|
+
|
|
148
|
+
<details>
|
|
149
|
+
<summary><strong>Required Dependencies</strong></summary>
|
|
150
|
+
|
|
151
|
+
- **Node.js** 18+
|
|
152
|
+
- **TypeScript** 5.3+
|
|
153
|
+
- **Google Cloud SDK** (optional, for Google Cloud provider)
|
|
154
|
+
|
|
155
|
+
For Google Cloud provider:
|
|
156
|
+
```bash
|
|
157
|
+
npm install @google-cloud/aiplatform @google/genai
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
</details>
|
|
161
|
+
|
|
162
|
+
## Configuration
|
|
163
|
+
|
|
164
|
+
<details>
|
|
165
|
+
<summary><strong>Environment Setup</strong></summary>
|
|
166
|
+
|
|
167
|
+
Create a `.env` file in your project root:
|
|
168
|
+
|
|
169
|
+
```env
|
|
170
|
+
# Default provider
|
|
171
|
+
TTI_DEFAULT_PROVIDER=google-cloud
|
|
172
|
+
|
|
173
|
+
# Logging level (debug, info, warn, error, silent)
|
|
174
|
+
TTI_LOG_LEVEL=info
|
|
175
|
+
|
|
176
|
+
# Google Cloud (recommended for EU/GDPR)
|
|
177
|
+
GOOGLE_CLOUD_PROJECT=your-project-id
|
|
178
|
+
GOOGLE_APPLICATION_CREDENTIALS=./service-account.json
|
|
179
|
+
GOOGLE_CLOUD_REGION=europe-west4 # Recommended for Gemini
|
|
180
|
+
|
|
181
|
+
# Eden AI (experimental)
|
|
182
|
+
EDENAI_API_KEY=your-api-key
|
|
183
|
+
|
|
184
|
+
# IONOS (experimental)
|
|
185
|
+
IONOS_API_KEY=your-api-key
|
|
186
|
+
IONOS_API_URL=https://api.ionos.cloud/ai/v1
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
</details>
|
|
190
|
+
|
|
191
|
+
## Providers & Models
|
|
192
|
+
|
|
193
|
+
### Google Cloud (Recommended)
|
|
194
|
+
|
|
195
|
+
| Model | ID | Character Consistency | EU Regions |
|
|
196
|
+
|-------|-----|----------------------|------------|
|
|
197
|
+
| **Imagen 3** | `imagen-3` | No | All EU regions |
|
|
198
|
+
| **Gemini Flash Image** | `gemini-flash-image` | **Yes** | europe-west1, europe-west4, europe-north1 |
|
|
199
|
+
|
|
200
|
+
**Important:** `gemini-flash-image` is **NOT available** in `europe-west3` (Frankfurt)!
|
|
201
|
+
|
|
202
|
+
### Eden AI (Experimental)
|
|
203
|
+
|
|
204
|
+
| Model | ID | Notes |
|
|
205
|
+
|-------|-----|-------|
|
|
206
|
+
| OpenAI DALL-E | `openai` | Via Eden AI aggregator |
|
|
207
|
+
| Stability AI | `stabilityai` | Via Eden AI aggregator |
|
|
208
|
+
| Replicate | `replicate` | Via Eden AI aggregator |
|
|
209
|
+
|
|
210
|
+
### IONOS (Experimental)
|
|
211
|
+
|
|
212
|
+
| Model | ID | Notes |
|
|
213
|
+
|-------|-----|-------|
|
|
214
|
+
| Default | `default` | OpenAI-compatible API |
|
|
215
|
+
|
|
216
|
+
### Google Cloud Region Availability
|
|
217
|
+
|
|
218
|
+
| Region | Location | Imagen 3 | Gemini Flash Image |
|
|
219
|
+
|--------|----------|----------|-------------------|
|
|
220
|
+
| `europe-west1` | Belgium | Yes | Yes |
|
|
221
|
+
| `europe-west3` | Frankfurt | Yes | **No** |
|
|
222
|
+
| `europe-west4` | Netherlands | Yes | **Yes (Recommended)** |
|
|
223
|
+
| `europe-north1` | Finland | Yes | Yes |
|
|
224
|
+
| `europe-west9` | Paris | Yes | No |
|
|
225
|
+
|
|
226
|
+
## Character Consistency
|
|
227
|
+
|
|
228
|
+
Generate consistent characters across multiple images - perfect for children's book illustrations:
|
|
229
|
+
|
|
230
|
+
```typescript
|
|
231
|
+
// Step 1: Create a character
|
|
232
|
+
const bear = await service.generate({
|
|
233
|
+
prompt: 'A cute cartoon bear with a red hat, watercolor style',
|
|
234
|
+
model: 'gemini-flash-image',
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
// Step 2: Use in different scenes
|
|
238
|
+
const scenes = ['playing in the park', 'reading a book', 'eating honey'];
|
|
239
|
+
|
|
240
|
+
for (const scene of scenes) {
|
|
241
|
+
const result = await service.generate({
|
|
242
|
+
prompt: scene,
|
|
243
|
+
model: 'gemini-flash-image',
|
|
244
|
+
referenceImages: [{ base64: bear.images[0].base64!, mimeType: 'image/png' }],
|
|
245
|
+
subjectDescription: 'cute cartoon bear with red hat',
|
|
246
|
+
});
|
|
247
|
+
// Save result...
|
|
248
|
+
}
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
**Requirements:**
|
|
252
|
+
- Model must be `gemini-flash-image`
|
|
253
|
+
- `subjectDescription` is required when using `referenceImages`
|
|
254
|
+
|
|
255
|
+
## GDPR / Compliance
|
|
256
|
+
|
|
257
|
+
### Provider Compliance Overview
|
|
258
|
+
|
|
259
|
+
| Provider | DPA | GDPR | EU Data Residency | Document |
|
|
260
|
+
|----------|-----|------|-------------------|----------|
|
|
261
|
+
| **Google Cloud** | Yes | Yes | Yes | [CDPA](https://cloud.google.com/terms/data-processing-addendum) |
|
|
262
|
+
| **Eden AI** | Yes | Depends* | Depends* | [Privacy Policy](https://www.edenai.co/privacy-policy) |
|
|
263
|
+
| **IONOS** | Yes | Yes | Yes | [AGB](https://cloud.ionos.de/agb) |
|
|
264
|
+
|
|
265
|
+
*Eden AI is an aggregator - compliance depends on the underlying provider.
|
|
266
|
+
|
|
267
|
+
### Google Cloud Data Usage
|
|
268
|
+
|
|
269
|
+
- Customer data is **NOT used for training** AI models
|
|
270
|
+
- Data stays in configured region (e.g., `europe-west4`)
|
|
271
|
+
- Zero data retention option available
|
|
272
|
+
- [Vertex AI Privacy Whitepaper](https://services.google.com/fh/files/misc/genai_privacy_google_cloud_202308.pdf)
|
|
273
|
+
|
|
274
|
+
<details>
|
|
275
|
+
<summary><strong>Checking EU Region Status</strong></summary>
|
|
276
|
+
|
|
277
|
+
```typescript
|
|
278
|
+
import { GoogleCloudTTIProvider } from '@loonylabs/tti-middleware';
|
|
279
|
+
|
|
280
|
+
const provider = new GoogleCloudTTIProvider({
|
|
281
|
+
projectId: 'my-project',
|
|
282
|
+
region: 'europe-west4',
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
console.log('Is EU region:', provider.isEURegion()); // true
|
|
286
|
+
console.log('Current region:', provider.getRegion()); // 'europe-west4'
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
</details>
|
|
290
|
+
|
|
291
|
+
## API Reference
|
|
292
|
+
|
|
293
|
+
### TTIService
|
|
294
|
+
|
|
295
|
+
```typescript
|
|
296
|
+
class TTIService {
|
|
297
|
+
registerProvider(provider: BaseTTIProvider): void;
|
|
298
|
+
generate(request: TTIRequest, provider?: TTIProvider): Promise<TTIResponse>;
|
|
299
|
+
getProvider(name: TTIProvider): BaseTTIProvider | undefined;
|
|
300
|
+
listAllModels(): Array<{ provider: TTIProvider; models: ModelInfo[] }>;
|
|
301
|
+
}
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
### TTIRequest
|
|
305
|
+
|
|
306
|
+
```typescript
|
|
307
|
+
interface TTIRequest {
|
|
308
|
+
prompt: string;
|
|
309
|
+
model?: string; // 'imagen-3', 'gemini-flash-image', etc.
|
|
310
|
+
n?: number; // Number of images (default: 1)
|
|
311
|
+
aspectRatio?: string; // '1:1', '16:9', '4:3', etc.
|
|
312
|
+
|
|
313
|
+
// Character consistency
|
|
314
|
+
referenceImages?: TTIReferenceImage[];
|
|
315
|
+
subjectDescription?: string;
|
|
316
|
+
|
|
317
|
+
// Retry configuration
|
|
318
|
+
retry?: boolean | RetryOptions; // true (default), false, or custom config
|
|
319
|
+
|
|
320
|
+
providerOptions?: Record<string, unknown>;
|
|
321
|
+
}
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
### TTIResponse
|
|
325
|
+
|
|
326
|
+
```typescript
|
|
327
|
+
interface TTIResponse {
|
|
328
|
+
images: TTIImage[];
|
|
329
|
+
metadata: {
|
|
330
|
+
provider: string;
|
|
331
|
+
model: string;
|
|
332
|
+
region?: string;
|
|
333
|
+
duration: number;
|
|
334
|
+
};
|
|
335
|
+
usage: {
|
|
336
|
+
imagesGenerated: number;
|
|
337
|
+
modelId: string;
|
|
338
|
+
};
|
|
339
|
+
billing?: { // Only if provider returns costs
|
|
340
|
+
cost: number;
|
|
341
|
+
currency: string;
|
|
342
|
+
source: 'provider' | 'estimated';
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
## Advanced Features
|
|
348
|
+
|
|
349
|
+
<details>
|
|
350
|
+
<summary><strong>Retry Configuration</strong></summary>
|
|
351
|
+
|
|
352
|
+
Automatic retry for rate limit errors (429):
|
|
353
|
+
|
|
354
|
+
```typescript
|
|
355
|
+
// Default: 2 retries, 1s delay, no backoff
|
|
356
|
+
const result = await service.generate({
|
|
357
|
+
prompt: 'A sunset over mountains',
|
|
358
|
+
model: 'imagen-3',
|
|
359
|
+
// retry: true (default)
|
|
360
|
+
});
|
|
361
|
+
|
|
362
|
+
// Custom retry configuration
|
|
363
|
+
const result = await service.generate({
|
|
364
|
+
prompt: 'A sunset over mountains',
|
|
365
|
+
model: 'imagen-3',
|
|
366
|
+
retry: {
|
|
367
|
+
maxRetries: 3,
|
|
368
|
+
delayMs: 2000,
|
|
369
|
+
incrementalBackoff: true, // 2s, 4s, 6s...
|
|
370
|
+
},
|
|
371
|
+
});
|
|
372
|
+
|
|
373
|
+
// Disable retry
|
|
374
|
+
const result = await service.generate({
|
|
375
|
+
prompt: 'A sunset over mountains',
|
|
376
|
+
model: 'imagen-3',
|
|
377
|
+
retry: false,
|
|
378
|
+
});
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
| Option | Default | Description |
|
|
382
|
+
|--------|---------|-------------|
|
|
383
|
+
| `maxRetries` | 2 | Maximum retry attempts |
|
|
384
|
+
| `delayMs` | 1000 | Base delay between retries (ms) |
|
|
385
|
+
| `incrementalBackoff` | false | If true: delay x attempt number |
|
|
386
|
+
|
|
387
|
+
</details>
|
|
388
|
+
|
|
389
|
+
<details>
|
|
390
|
+
<summary><strong>Logging Configuration</strong></summary>
|
|
391
|
+
|
|
392
|
+
Control logging via environment variable or API:
|
|
393
|
+
|
|
394
|
+
```typescript
|
|
395
|
+
import { setLogLevel } from '@loonylabs/tti-middleware';
|
|
396
|
+
|
|
397
|
+
// Set log level programmatically
|
|
398
|
+
setLogLevel('warn'); // Only show warnings and errors
|
|
399
|
+
|
|
400
|
+
// Or via environment variable
|
|
401
|
+
// TTI_LOG_LEVEL=error
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
Available levels: `debug`, `info`, `warn`, `error`, `silent`
|
|
405
|
+
|
|
406
|
+
</details>
|
|
407
|
+
|
|
408
|
+
<details>
|
|
409
|
+
<summary><strong>Error Handling</strong></summary>
|
|
410
|
+
|
|
411
|
+
Typed error classes for precise error handling:
|
|
412
|
+
|
|
413
|
+
```typescript
|
|
414
|
+
import {
|
|
415
|
+
TTIError,
|
|
416
|
+
InvalidConfigError,
|
|
417
|
+
QuotaExceededError,
|
|
418
|
+
ProviderUnavailableError,
|
|
419
|
+
GenerationFailedError,
|
|
420
|
+
NetworkError,
|
|
421
|
+
CapabilityNotSupportedError,
|
|
422
|
+
} from '@loonylabs/tti-middleware';
|
|
423
|
+
|
|
424
|
+
try {
|
|
425
|
+
const result = await service.generate({ prompt: 'test' });
|
|
426
|
+
} catch (error) {
|
|
427
|
+
if (error instanceof QuotaExceededError) {
|
|
428
|
+
console.log('Rate limit hit, try again later');
|
|
429
|
+
} else if (error instanceof CapabilityNotSupportedError) {
|
|
430
|
+
console.log('Model does not support this feature');
|
|
431
|
+
} else if (error instanceof TTIError) {
|
|
432
|
+
console.log(`TTI Error [${error.code}]: ${error.message}`);
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
```
|
|
436
|
+
|
|
437
|
+
</details>
|
|
438
|
+
|
|
439
|
+
## Testing
|
|
440
|
+
|
|
441
|
+
```bash
|
|
442
|
+
# Run all tests
|
|
443
|
+
npm test
|
|
444
|
+
|
|
445
|
+
# Unit tests only (123 tests, >95% coverage)
|
|
446
|
+
npm run test:unit
|
|
447
|
+
|
|
448
|
+
# Unit tests with watch mode
|
|
449
|
+
npm run test:unit:watch
|
|
450
|
+
|
|
451
|
+
# Unit tests with coverage report
|
|
452
|
+
npm run test:unit:coverage
|
|
453
|
+
|
|
454
|
+
# Integration tests (requires TTI_INTEGRATION_TESTS=true)
|
|
455
|
+
npm run test:integration
|
|
456
|
+
|
|
457
|
+
# CI/CD mode (unit tests only, in band)
|
|
458
|
+
npm run test:ci
|
|
459
|
+
|
|
460
|
+
# Manual test scripts
|
|
461
|
+
npm run test:manual:google-cloud
|
|
462
|
+
```
|
|
463
|
+
|
|
464
|
+
### Integration Tests
|
|
465
|
+
|
|
466
|
+
Integration tests make real API calls. They are **skipped by default**.
|
|
467
|
+
|
|
468
|
+
```bash
|
|
469
|
+
# Enable and run integration tests
|
|
470
|
+
TTI_INTEGRATION_TESTS=true npm run test:integration
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
**Prerequisites:**
|
|
474
|
+
- `GOOGLE_CLOUD_PROJECT` environment variable
|
|
475
|
+
- `GOOGLE_APPLICATION_CREDENTIALS` pointing to service account JSON
|
|
476
|
+
|
|
477
|
+
## Documentation
|
|
478
|
+
|
|
479
|
+
- [Getting Started](docs/getting-started.md) - Detailed setup guide
|
|
480
|
+
- [Google Cloud Provider](docs/providers/google-cloud.md) - Imagen 3 & Gemini Flash Image
|
|
481
|
+
- [GDPR/Compliance](docs/compliance.md) - Data processing agreements
|
|
482
|
+
- [Testing Guide](docs/testing.md) - Unit & integration tests
|
|
483
|
+
- [CHANGELOG](CHANGELOG.md) - Release notes
|
|
484
|
+
|
|
485
|
+
## Contributing
|
|
486
|
+
|
|
487
|
+
We welcome contributions! Please ensure:
|
|
488
|
+
|
|
489
|
+
1. **Tests:** Add tests for new features
|
|
490
|
+
2. **Linting:** Run `npm run lint` before committing
|
|
491
|
+
3. **Conventions:** Follow the existing project structure
|
|
492
|
+
|
|
493
|
+
1. Fork the repository
|
|
494
|
+
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
|
|
495
|
+
3. Commit your changes (`git commit -m 'Add some amazing feature'`)
|
|
496
|
+
4. Push to the branch (`git push origin feature/amazing-feature`)
|
|
497
|
+
5. Open a Pull Request
|
|
498
|
+
|
|
499
|
+
## License
|
|
500
|
+
|
|
501
|
+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
|
502
|
+
|
|
503
|
+
## Links
|
|
504
|
+
|
|
505
|
+
- [Documentation](https://github.com/loonylabs-dev/tti-middleware/docs)
|
|
506
|
+
- [Issues](https://github.com/loonylabs-dev/tti-middleware/issues)
|
|
507
|
+
- [NPM Package](https://www.npmjs.com/package/@loonylabs/tti-middleware)
|
|
508
|
+
|
|
509
|
+
---
|
|
510
|
+
|
|
511
|
+
<div align="center">
|
|
512
|
+
|
|
513
|
+
**Made with care by the LoonyLabs Team**
|
|
514
|
+
|
|
515
|
+
[](https://github.com/loonylabs-dev/tti-middleware/stargazers)
|
|
516
|
+
[](https://github.com/loonylabs-dev)
|
|
517
|
+
|
|
518
|
+
</div>
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./middleware/types"), exports);
|
|
18
|
+
__exportStar(require("./middleware/services/tti"), exports);
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./tti.service"), exports);
|
|
18
|
+
__exportStar(require("./providers"), exports);
|