@umituz/web-ai 1.0.0 → 1.0.2
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/dist/{ABTesting-DDqNhHtP.d.ts → AIErrors-B2ogd1PB.d.ts} +14 -1
- package/dist/{ABTesting-DWBtKTMQ.d.cts → AIErrors-C5EasV_c.d.cts} +14 -1
- package/dist/{ProviderConfig-a55tLhWT.d.cts → ProviderConfig-DIFa9nmG.d.cts} +10 -1
- package/dist/{ProviderConfig-a55tLhWT.d.ts → ProviderConfig-DIFa9nmG.d.ts} +10 -1
- package/dist/chat/index.cjs +114 -23
- package/dist/chat/index.cjs.map +1 -1
- package/dist/chat/index.d.cts +4 -4
- package/dist/chat/index.d.ts +4 -4
- package/dist/chat/index.js +114 -23
- package/dist/chat/index.js.map +1 -1
- package/dist/{chat.service-DBKq9I2c.d.cts → chat.service-CL1qtYxe.d.cts} +7 -7
- package/dist/{chat.service-RQn8UTXD.d.ts → chat.service-q05GnhEm.d.ts} +7 -7
- package/dist/content/index.cjs +506 -193
- package/dist/content/index.cjs.map +1 -1
- package/dist/content/index.d.cts +7 -8
- package/dist/content/index.d.ts +7 -8
- package/dist/content/index.js +506 -193
- package/dist/content/index.js.map +1 -1
- package/dist/core/index.cjs +122 -15
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +13 -31
- package/dist/core/index.d.ts +13 -31
- package/dist/core/index.js +119 -16
- package/dist/core/index.js.map +1 -1
- package/dist/{create-ai-BhNaz86i.d.ts → create-ai-9PW752z8.d.ts} +14 -21
- package/dist/{create-ai-DGZFBOA1.d.cts → create-ai-CXYKPK6G.d.cts} +14 -21
- package/dist/hooks/index.cjs +631 -179
- package/dist/hooks/index.cjs.map +1 -1
- package/dist/hooks/index.d.cts +33 -7
- package/dist/hooks/index.d.ts +33 -7
- package/dist/hooks/index.js +631 -180
- package/dist/hooks/index.js.map +1 -1
- package/dist/index-DIHz8_OJ.d.ts +48 -0
- package/dist/index-DKHNcMbl.d.cts +48 -0
- package/dist/index.cjs +666 -104
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8 -7
- package/dist/index.d.ts +8 -7
- package/dist/index.js +645 -105
- package/dist/index.js.map +1 -1
- package/dist/{provider.factory-COsnprLH.d.cts → provider.factory-BxsfK4WW.d.cts} +1 -1
- package/dist/{provider.factory-CpWFyjbw.d.ts → provider.factory-DfDfk0dK.d.ts} +1 -1
- package/dist/providers/index.cjs +973 -130
- package/dist/providers/index.cjs.map +1 -1
- package/dist/providers/index.d.cts +84 -18
- package/dist/providers/index.d.ts +84 -18
- package/dist/providers/index.js +956 -131
- package/dist/providers/index.js.map +1 -1
- package/dist/text-generation.service-BQO3Tvz2.d.cts +66 -0
- package/dist/text-generation.service-CcYQM6Ch.d.ts +66 -0
- package/dist/wizard/index.d.cts +1 -1
- package/dist/wizard/index.d.ts +1 -1
- package/package.json +9 -1
- package/dist/index-DjX9ZKuM.d.cts +0 -14
- package/dist/index-DxLvE588.d.ts +0 -14
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { S as Sentiment, E as Emotion, C as ContentType, a as ContentTone } from './ContentGeneration-B6iK2B33.js';
|
|
2
|
+
import { A as AIError } from './index-DIHz8_OJ.js';
|
|
2
3
|
|
|
3
4
|
type AspectRatio = '1:1' | '16:9' | '9:16' | '4:3' | '3:4';
|
|
4
5
|
type ImageQuality = 'standard' | 'hd' | '4k';
|
|
@@ -181,4 +182,16 @@ interface ABTestRequest {
|
|
|
181
182
|
goals: string[];
|
|
182
183
|
}
|
|
183
184
|
|
|
184
|
-
|
|
185
|
+
type AIErrorCode = 'VALIDATION_ERROR' | 'PROVIDER_UNAVAILABLE' | 'PROVIDER_QUOTA_EXHAUSTED' | 'PROVIDER_ERROR' | 'NETWORK_ERROR' | 'TIMEOUT' | 'ABORTED' | 'PARSE_ERROR' | 'NO_RESULT' | 'UNKNOWN';
|
|
186
|
+
|
|
187
|
+
declare class ValidationError extends AIError {
|
|
188
|
+
constructor(message: string);
|
|
189
|
+
}
|
|
190
|
+
declare class ProviderUnavailableError extends AIError {
|
|
191
|
+
constructor(providerId: string);
|
|
192
|
+
}
|
|
193
|
+
declare class ProviderQuotaExhaustedError extends AIError {
|
|
194
|
+
constructor(providerId: string);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
export { type AIErrorCode as A, type ContentAnalysisRequest as C, type GenerationResult as G, type ImageGenerationInput as I, type KeywordAnalysis as K, MOTION_OPTIONS as M, ProviderQuotaExhaustedError as P, type SentimentAnalysisResult as S, type VideoGenerationInput as V, type ContentAnalysisResult as a, type SEOOptimizationRequest as b, type SEOOptimizationResult as c, type SEOScoreBreakdown as d, type ABTestRequest as e, type ABTestPrediction as f, type ABTestComparison as g, type GenerationProgress as h, type GenerationStatus as i, type GenerationType as j, type ImageQuality as k, type VideoQuality as l, type AspectRatio as m, type ABTestVariant as n, ASPECT_RATIO_OPTIONS as o, type CreditCost as p, type GenerationMetadata as q, IMAGE_QUALITY_OPTIONS as r, ProviderUnavailableError as s, STYLE_PRESETS as t, VIDEO_DURATION_OPTIONS_SECONDS as u, VIDEO_QUALITY_OPTIONS as v, ValidationError as w };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { S as Sentiment, E as Emotion, C as ContentType, a as ContentTone } from './ContentGeneration-B6iK2B33.cjs';
|
|
2
|
+
import { A as AIError } from './index-DKHNcMbl.cjs';
|
|
2
3
|
|
|
3
4
|
type AspectRatio = '1:1' | '16:9' | '9:16' | '4:3' | '3:4';
|
|
4
5
|
type ImageQuality = 'standard' | 'hd' | '4k';
|
|
@@ -181,4 +182,16 @@ interface ABTestRequest {
|
|
|
181
182
|
goals: string[];
|
|
182
183
|
}
|
|
183
184
|
|
|
184
|
-
|
|
185
|
+
type AIErrorCode = 'VALIDATION_ERROR' | 'PROVIDER_UNAVAILABLE' | 'PROVIDER_QUOTA_EXHAUSTED' | 'PROVIDER_ERROR' | 'NETWORK_ERROR' | 'TIMEOUT' | 'ABORTED' | 'PARSE_ERROR' | 'NO_RESULT' | 'UNKNOWN';
|
|
186
|
+
|
|
187
|
+
declare class ValidationError extends AIError {
|
|
188
|
+
constructor(message: string);
|
|
189
|
+
}
|
|
190
|
+
declare class ProviderUnavailableError extends AIError {
|
|
191
|
+
constructor(providerId: string);
|
|
192
|
+
}
|
|
193
|
+
declare class ProviderQuotaExhaustedError extends AIError {
|
|
194
|
+
constructor(providerId: string);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
export { type AIErrorCode as A, type ContentAnalysisRequest as C, type GenerationResult as G, type ImageGenerationInput as I, type KeywordAnalysis as K, MOTION_OPTIONS as M, ProviderQuotaExhaustedError as P, type SentimentAnalysisResult as S, type VideoGenerationInput as V, type ContentAnalysisResult as a, type SEOOptimizationRequest as b, type SEOOptimizationResult as c, type SEOScoreBreakdown as d, type ABTestRequest as e, type ABTestPrediction as f, type ABTestComparison as g, type GenerationProgress as h, type GenerationStatus as i, type GenerationType as j, type ImageQuality as k, type VideoQuality as l, type AspectRatio as m, type ABTestVariant as n, ASPECT_RATIO_OPTIONS as o, type CreditCost as p, type GenerationMetadata as q, IMAGE_QUALITY_OPTIONS as r, ProviderUnavailableError as s, STYLE_PRESETS as t, VIDEO_DURATION_OPTIONS_SECONDS as u, VIDEO_QUALITY_OPTIONS as v, ValidationError as w };
|
|
@@ -34,8 +34,17 @@ interface GeminiConfig extends BaseProviderConfig {
|
|
|
34
34
|
video?: string;
|
|
35
35
|
};
|
|
36
36
|
}
|
|
37
|
+
interface AnthropicConfig extends BaseProviderConfig {
|
|
38
|
+
models?: {
|
|
39
|
+
fast?: string;
|
|
40
|
+
balanced?: string;
|
|
41
|
+
powerful?: string;
|
|
42
|
+
};
|
|
43
|
+
effort?: 'low' | 'medium' | 'high';
|
|
44
|
+
}
|
|
37
45
|
interface ProviderConfig {
|
|
38
46
|
priority: string[];
|
|
47
|
+
anthropic?: AnthropicConfig;
|
|
39
48
|
groq?: GroqConfig;
|
|
40
49
|
fal?: FalConfig;
|
|
41
50
|
pruna?: PrunaConfig;
|
|
@@ -96,4 +105,4 @@ interface GeneratedContent {
|
|
|
96
105
|
createdAt: string;
|
|
97
106
|
}
|
|
98
107
|
|
|
99
|
-
export type { BaseProviderConfig as B, FalConfig as F, GeneratedContent as G, ImageGenerationRequest as I, PrunaConfig as P, TextGenerationRequest as T, VideoGenerationRequest as V, ImageToVideoRequest as a, VideoToVideoRequest as b, GeminiConfig as c, ProviderConfig as d, GenerationRequest as e, GroqConfig as f, ProviderHealth as g, ProviderType as h };
|
|
108
|
+
export type { AnthropicConfig as A, BaseProviderConfig as B, FalConfig as F, GeneratedContent as G, ImageGenerationRequest as I, PrunaConfig as P, TextGenerationRequest as T, VideoGenerationRequest as V, ImageToVideoRequest as a, VideoToVideoRequest as b, GeminiConfig as c, ProviderConfig as d, GenerationRequest as e, GroqConfig as f, ProviderHealth as g, ProviderType as h };
|
|
@@ -34,8 +34,17 @@ interface GeminiConfig extends BaseProviderConfig {
|
|
|
34
34
|
video?: string;
|
|
35
35
|
};
|
|
36
36
|
}
|
|
37
|
+
interface AnthropicConfig extends BaseProviderConfig {
|
|
38
|
+
models?: {
|
|
39
|
+
fast?: string;
|
|
40
|
+
balanced?: string;
|
|
41
|
+
powerful?: string;
|
|
42
|
+
};
|
|
43
|
+
effort?: 'low' | 'medium' | 'high';
|
|
44
|
+
}
|
|
37
45
|
interface ProviderConfig {
|
|
38
46
|
priority: string[];
|
|
47
|
+
anthropic?: AnthropicConfig;
|
|
39
48
|
groq?: GroqConfig;
|
|
40
49
|
fal?: FalConfig;
|
|
41
50
|
pruna?: PrunaConfig;
|
|
@@ -96,4 +105,4 @@ interface GeneratedContent {
|
|
|
96
105
|
createdAt: string;
|
|
97
106
|
}
|
|
98
107
|
|
|
99
|
-
export type { BaseProviderConfig as B, FalConfig as F, GeneratedContent as G, ImageGenerationRequest as I, PrunaConfig as P, TextGenerationRequest as T, VideoGenerationRequest as V, ImageToVideoRequest as a, VideoToVideoRequest as b, GeminiConfig as c, ProviderConfig as d, GenerationRequest as e, GroqConfig as f, ProviderHealth as g, ProviderType as h };
|
|
108
|
+
export type { AnthropicConfig as A, BaseProviderConfig as B, FalConfig as F, GeneratedContent as G, ImageGenerationRequest as I, PrunaConfig as P, TextGenerationRequest as T, VideoGenerationRequest as V, ImageToVideoRequest as a, VideoToVideoRequest as b, GeminiConfig as c, ProviderConfig as d, GenerationRequest as e, GroqConfig as f, ProviderHealth as g, ProviderType as h };
|
package/dist/chat/index.cjs
CHANGED
|
@@ -1,17 +1,93 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
// src/core/errors/ai-error-types.ts
|
|
4
|
+
var AIErrorType = /* @__PURE__ */ ((AIErrorType2) => {
|
|
5
|
+
AIErrorType2["INVALID_API_KEY"] = "INVALID_API_KEY";
|
|
6
|
+
AIErrorType2["MISSING_CONFIG"] = "MISSING_CONFIG";
|
|
7
|
+
AIErrorType2["NETWORK_ERROR"] = "NETWORK_ERROR";
|
|
8
|
+
AIErrorType2["ABORT_ERROR"] = "ABORT_ERROR";
|
|
9
|
+
AIErrorType2["RATE_LIMIT_ERROR"] = "RATE_LIMIT_ERROR";
|
|
10
|
+
AIErrorType2["SERVER_ERROR"] = "SERVER_ERROR";
|
|
11
|
+
AIErrorType2["CLIENT_ERROR"] = "CLIENT_ERROR";
|
|
12
|
+
AIErrorType2["UNKNOWN_ERROR"] = "UNKNOWN_ERROR";
|
|
13
|
+
return AIErrorType2;
|
|
14
|
+
})(AIErrorType || {});
|
|
15
|
+
|
|
3
16
|
// src/core/errors/ai-error.ts
|
|
4
|
-
var
|
|
17
|
+
var KNOWN_ERROR_TYPES = new Set(Object.values(AIErrorType));
|
|
18
|
+
function mapCodeToType(code) {
|
|
19
|
+
switch (code) {
|
|
20
|
+
case "VALIDATION_ERROR":
|
|
21
|
+
case "CLIENT_ERROR":
|
|
22
|
+
return "CLIENT_ERROR" /* CLIENT_ERROR */;
|
|
23
|
+
case "INVALID_API_KEY":
|
|
24
|
+
return "INVALID_API_KEY" /* INVALID_API_KEY */;
|
|
25
|
+
case "MISSING_CONFIG":
|
|
26
|
+
case "PROVIDER_UNAVAILABLE":
|
|
27
|
+
return "MISSING_CONFIG" /* MISSING_CONFIG */;
|
|
28
|
+
case "PROVIDER_QUOTA_EXHAUSTED":
|
|
29
|
+
case "RATE_LIMIT_ERROR":
|
|
30
|
+
return "RATE_LIMIT_ERROR" /* RATE_LIMIT_ERROR */;
|
|
31
|
+
case "NETWORK_ERROR":
|
|
32
|
+
case "TIMEOUT":
|
|
33
|
+
return "NETWORK_ERROR" /* NETWORK_ERROR */;
|
|
34
|
+
case "ABORT_ERROR":
|
|
35
|
+
case "ABORTED":
|
|
36
|
+
return "ABORT_ERROR" /* ABORT_ERROR */;
|
|
37
|
+
case "SERVER_ERROR":
|
|
38
|
+
case "PROVIDER_ERROR":
|
|
39
|
+
case "NO_RESULT":
|
|
40
|
+
return "SERVER_ERROR" /* SERVER_ERROR */;
|
|
41
|
+
default:
|
|
42
|
+
return "UNKNOWN_ERROR" /* UNKNOWN_ERROR */;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
function mapMessageToCode(message, fallback = "UNKNOWN") {
|
|
46
|
+
const lower = message.toLowerCase();
|
|
47
|
+
if (lower.includes("validation")) return "VALIDATION_ERROR";
|
|
48
|
+
if (lower.includes("quota")) return "PROVIDER_QUOTA_EXHAUSTED";
|
|
49
|
+
if (lower.includes("unavailable")) return "PROVIDER_UNAVAILABLE";
|
|
50
|
+
if (lower.includes("timeout") || lower.includes("aborted")) {
|
|
51
|
+
return lower.includes("aborted") ? "ABORTED" : "TIMEOUT";
|
|
52
|
+
}
|
|
53
|
+
if (lower.includes("parse") || lower.includes("json")) return "PARSE_ERROR";
|
|
54
|
+
if (lower.includes("no result")) return "NO_RESULT";
|
|
55
|
+
if (lower.includes("network") || lower.includes("fetch")) return "NETWORK_ERROR";
|
|
56
|
+
return fallback;
|
|
57
|
+
}
|
|
58
|
+
var AIError = class _AIError extends Error {
|
|
5
59
|
type;
|
|
60
|
+
code;
|
|
6
61
|
cause;
|
|
7
62
|
metadata;
|
|
8
|
-
constructor(
|
|
9
|
-
|
|
63
|
+
constructor(typeOrMessage, messageOrCode, cause, metadata = {}) {
|
|
64
|
+
let effectiveType;
|
|
65
|
+
let effectiveMessage;
|
|
66
|
+
let effectiveCode;
|
|
67
|
+
if (KNOWN_ERROR_TYPES.has(typeOrMessage)) {
|
|
68
|
+
effectiveType = typeOrMessage;
|
|
69
|
+
effectiveMessage = messageOrCode ?? "";
|
|
70
|
+
effectiveCode = effectiveType;
|
|
71
|
+
} else {
|
|
72
|
+
effectiveMessage = typeOrMessage;
|
|
73
|
+
effectiveCode = messageOrCode ?? "UNKNOWN";
|
|
74
|
+
effectiveType = mapCodeToType(effectiveCode);
|
|
75
|
+
}
|
|
76
|
+
super(effectiveMessage);
|
|
10
77
|
this.name = "AIError";
|
|
11
|
-
this.type =
|
|
78
|
+
this.type = effectiveType;
|
|
79
|
+
this.code = effectiveCode;
|
|
12
80
|
this.cause = cause;
|
|
13
81
|
this.metadata = metadata;
|
|
14
82
|
}
|
|
83
|
+
static from(error, fallbackCode = "UNKNOWN") {
|
|
84
|
+
if (error instanceof _AIError) return error;
|
|
85
|
+
if (error instanceof Error) {
|
|
86
|
+
const code = mapMessageToCode(error.message, fallbackCode);
|
|
87
|
+
return new _AIError(error.message, code, error);
|
|
88
|
+
}
|
|
89
|
+
return new _AIError(String(error), fallbackCode, error);
|
|
90
|
+
}
|
|
15
91
|
toString() {
|
|
16
92
|
const statusPart = typeof this.metadata.status === "number" ? ` (HTTP ${this.metadata.status})` : "";
|
|
17
93
|
return `${this.name} [${this.type}]: ${this.message}${statusPart}`;
|
|
@@ -20,6 +96,7 @@ var AIError = class extends Error {
|
|
|
20
96
|
return {
|
|
21
97
|
name: this.name,
|
|
22
98
|
type: this.type,
|
|
99
|
+
code: this.code,
|
|
23
100
|
message: this.message,
|
|
24
101
|
metadata: this.metadata
|
|
25
102
|
};
|
|
@@ -120,12 +197,16 @@ var ProviderFactory = class {
|
|
|
120
197
|
let wake = null;
|
|
121
198
|
let finished = false;
|
|
122
199
|
let failure;
|
|
200
|
+
const controller = new AbortController();
|
|
201
|
+
const onAbort = () => controller.abort();
|
|
202
|
+
request.signal?.addEventListener("abort", onAbort);
|
|
203
|
+
const effectiveRequest = { ...request, signal: controller.signal };
|
|
123
204
|
const notify = () => {
|
|
124
205
|
const resolve = wake;
|
|
125
206
|
wake = null;
|
|
126
207
|
resolve?.();
|
|
127
208
|
};
|
|
128
|
-
const completion = this.chatStream(
|
|
209
|
+
const completion = this.chatStream(effectiveRequest, {
|
|
129
210
|
onChunk: (chunk) => {
|
|
130
211
|
queue.push(chunk);
|
|
131
212
|
notify();
|
|
@@ -141,18 +222,23 @@ var ProviderFactory = class {
|
|
|
141
222
|
notify();
|
|
142
223
|
}
|
|
143
224
|
);
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
225
|
+
try {
|
|
226
|
+
while (!finished || queue.length > 0) {
|
|
227
|
+
if (queue.length === 0 && !finished) {
|
|
228
|
+
await new Promise((resolve) => {
|
|
229
|
+
wake = resolve;
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
while (queue.length > 0) {
|
|
233
|
+
yield queue.shift();
|
|
234
|
+
}
|
|
235
|
+
if (failure) throw failure;
|
|
152
236
|
}
|
|
153
|
-
|
|
237
|
+
await completion;
|
|
238
|
+
} finally {
|
|
239
|
+
controller.abort();
|
|
240
|
+
request.signal?.removeEventListener("abort", onAbort);
|
|
154
241
|
}
|
|
155
|
-
await completion;
|
|
156
242
|
}
|
|
157
243
|
async generateJson(request) {
|
|
158
244
|
const effective = request.model || request.tier ? request : { ...request, tier: this.defaultTier };
|
|
@@ -422,9 +508,12 @@ var ChatService = class {
|
|
|
422
508
|
};
|
|
423
509
|
}
|
|
424
510
|
async getConversations() {
|
|
511
|
+
if (this.storage && "getConversations" in this.storage && typeof this.storage.getConversations === "function") {
|
|
512
|
+
return this.storage.getConversations();
|
|
513
|
+
}
|
|
425
514
|
return [];
|
|
426
515
|
}
|
|
427
|
-
async sendMessage(input) {
|
|
516
|
+
async sendMessage(input, signal) {
|
|
428
517
|
const userMessage = {
|
|
429
518
|
...messageFormatter.toChatMessage(input.text, "user"),
|
|
430
519
|
type: input.type ?? "text",
|
|
@@ -433,13 +522,14 @@ var ChatService = class {
|
|
|
433
522
|
const aiResponse = await this.generateAIResponse(
|
|
434
523
|
input.companionId,
|
|
435
524
|
input.text,
|
|
436
|
-
[]
|
|
525
|
+
[],
|
|
526
|
+
signal
|
|
437
527
|
);
|
|
438
528
|
return { userMessage, aiResponse };
|
|
439
529
|
}
|
|
440
|
-
async generateAIResponse(companionId, userMessage, context = []) {
|
|
530
|
+
async generateAIResponse(companionId, userMessage, context = [], signal) {
|
|
441
531
|
const result = await this.run({
|
|
442
|
-
...this.buildRequest(userMessage, context)
|
|
532
|
+
...this.buildRequest(userMessage, context, signal)
|
|
443
533
|
});
|
|
444
534
|
return {
|
|
445
535
|
...messageFormatter.toChatMessage(result.text, "assistant"),
|
|
@@ -455,12 +545,12 @@ var ChatService = class {
|
|
|
455
545
|
}
|
|
456
546
|
};
|
|
457
547
|
}
|
|
458
|
-
async generateStreamingResponse(userMessage, context, onChunk) {
|
|
459
|
-
const request = this.buildRequest(userMessage, context);
|
|
548
|
+
async generateStreamingResponse(userMessage, context, onChunk, signal) {
|
|
549
|
+
const request = this.buildRequest(userMessage, context, signal);
|
|
460
550
|
const result = await this.runStream(request, { onChunk });
|
|
461
551
|
return result.text;
|
|
462
552
|
}
|
|
463
|
-
buildRequest(userMessage, context) {
|
|
553
|
+
buildRequest(userMessage, context, signal) {
|
|
464
554
|
const messages = messageFormatter.toCoreMessages(context);
|
|
465
555
|
messages.push({ role: "user", content: userMessage });
|
|
466
556
|
return {
|
|
@@ -469,7 +559,8 @@ var ChatService = class {
|
|
|
469
559
|
model: this.config.model,
|
|
470
560
|
tier: this.config.tier,
|
|
471
561
|
temperature: this.config.temperature,
|
|
472
|
-
maxTokens: this.config.maxTokens
|
|
562
|
+
maxTokens: this.config.maxTokens,
|
|
563
|
+
...signal !== void 0 ? { signal } : {}
|
|
473
564
|
};
|
|
474
565
|
}
|
|
475
566
|
resolveSystemPrompt() {
|
package/dist/chat/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/core/errors/ai-error.ts","../../src/providers/base/provider.types.ts","../../src/content/domain/limits/ProviderTimingConfig.ts","../../src/providers/factory/provider.factory.ts","../../src/core/calculations/random-base36-suffix.ts","../../src/core/constants/identifier.constants.ts","../../src/chat/utils/chat-id-generator.ts","../../src/chat/utils/message-formatter.ts","../../src/chat/utils/prompt-strategy.ts","../../src/chat/services/chat.service.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["\nimport { AIErrorType } from \"./ai-error-types\";\n\nexport interface AIErrorMetadata {\n readonly status?: number;\n readonly url?: string;\n readonly [key: string]: unknown;\n}\n\nexport class AIError extends Error {\n public readonly type: AIErrorType;\n public readonly cause?: Error;\n public readonly metadata: AIErrorMetadata;\n\n constructor(\n type: AIErrorType,\n message: string,\n cause?: Error,\n metadata: AIErrorMetadata = {},\n ) {\n super(message);\n this.name = \"AIError\";\n this.type = type;\n this.cause = cause;\n this.metadata = metadata;\n }\n\n override toString(): string {\n const statusPart =\n typeof this.metadata.status === \"number\" ? ` (HTTP ${this.metadata.status})` : \"\";\n return `${this.name} [${this.type}]: ${this.message}${statusPart}`;\n }\n\n toJSON(): {\n name: string;\n type: AIErrorType;\n message: string;\n metadata: AIErrorMetadata;\n } {\n return {\n name: this.name,\n type: this.type,\n message: this.message,\n metadata: this.metadata,\n };\n }\n}\n","\nimport type {\n GenerationResult,\n ProviderHealth,\n StreamCallbacks,\n StructuredGeneration,\n StructuredTextRequest,\n TextRequest,\n TextTier,\n} from \"../../core/types\";\nimport type {\n GeneratedContent,\n ImageGenerationRequest,\n ImageToVideoRequest,\n TextGenerationRequest,\n VideoGenerationRequest,\n VideoToVideoRequest,\n} from \"../../content/domain/config/ProviderConfig\";\n\n/**\n * What a provider can serve. Replaces the old single `'multimodal'` type flag:\n * a provider declares exactly the capabilities it implements, and the factory\n * walks providers by capability when routing or failing over.\n */\nexport type ProviderCapability = \"text\" | \"image\" | \"video\";\n\n/** Cost estimation input — any generation request shape the fleet knows. */\nexport type CostEstimateRequest =\n | TextGenerationRequest\n | ImageGenerationRequest\n | VideoGenerationRequest;\n\nexport interface IProviderBase {\n readonly id: string;\n readonly name: string;\n readonly capabilities: ReadonlyArray<ProviderCapability>;\n healthCheck(): Promise<ProviderHealth>;\n estimateCost(request: CostEstimateRequest): Promise<number>;\n}\n\n/**\n * A provider that can turn conversations into text. This is the surface the\n * factory's `chat`/`chatStream` walk; model choice per quality tier is the\n * provider's own business (each maps neutral tiers onto its catalogue).\n */\nexport interface ITextProvider extends IProviderBase {\n generate(request: TextRequest): Promise<GenerationResult>;\n generateStructured<T>(request: StructuredTextRequest): Promise<StructuredGeneration<T>>;\n stream(request: TextRequest, callbacks: StreamCallbacks): Promise<GenerationResult>;\n resolveModel(tier: TextTier): string;\n}\n\n/**\n * A provider that generates media. Kept as B's media surface — image/video\n * request and result shapes are already provider-neutral.\n */\nexport interface IMediaProvider extends IProviderBase {\n generateImage(request: ImageGenerationRequest): Promise<GeneratedContent>;\n generateVideo(request: VideoGenerationRequest): Promise<GeneratedContent>;\n imageToVideo(request: ImageToVideoRequest): Promise<GeneratedContent>;\n videoToVideo(request: VideoToVideoRequest): Promise<GeneratedContent>;\n}\n\nexport type AnyProvider = ITextProvider | IMediaProvider;\n\nexport function isTextProvider(provider: AnyProvider): provider is ITextProvider {\n return provider.capabilities.includes(\"text\");\n}\n\nexport function isMediaProvider(provider: AnyProvider): provider is IMediaProvider {\n return provider.capabilities.includes(\"image\") || provider.capabilities.includes(\"video\");\n}\n","\nexport const ProviderTimingConfig = {\n DEFAULT_TIMEOUT_MS: 30_000,\n DEFAULT_RETRY_ATTEMPTS: 3,\n\n FAL_TIMEOUT_MS: 120_000,\n FAL_RETRY_ATTEMPTS: 2,\n\n GEMINI_TIMEOUT_MS: 60_000,\n GEMINI_RETRY_ATTEMPTS: 3,\n\n GROQ_TIMEOUT_MS: 30_000,\n GROQ_RETRY_ATTEMPTS: 3,\n\n HEALTH_CHECK_TTL_MS: 5 * 60 * 1000,\n\n RETRY_BACKOFF_BASE_MS: 1_000,\n} as const;\n","\nimport type {\n GenerationResult,\n ProviderHealth,\n StreamCallbacks,\n StructuredGeneration,\n StructuredTextRequest,\n TextRequest,\n TextTier,\n} from \"../../core/types\";\nimport { AIError, AIErrorType } from \"../../core/errors\";\nimport type {\n AnyProvider,\n IMediaProvider,\n ITextProvider,\n ProviderCapability,\n} from \"../base/provider.types\";\nimport { isTextProvider } from \"../base/provider.types\";\nimport type {\n GeneratedContent,\n ImageGenerationRequest,\n ImageToVideoRequest,\n VideoGenerationRequest,\n VideoToVideoRequest,\n} from \"../../content/domain/config/ProviderConfig\";\nimport type {\n ITextGenerator,\n TextGenerationOptions,\n} from \"../../content/domain/interfaces/ITextGenerator\";\nimport { ProviderTimingConfig } from \"../../content/domain/limits/ProviderTimingConfig\";\n\nexport interface ProviderFactoryConfig {\n /** Provider ids in preference order; unlisted providers follow in registration order. */\n priority?: ReadonlyArray<string>;\n fallbackEnabled?: boolean;\n /** Tier used when a request names neither a model nor a tier. */\n defaultTier?: TextTier;\n}\n\ninterface HealthCheckCache {\n health: ProviderHealth;\n timestamp: number;\n}\n\n/**\n * Composition-aware registry and router. Replaces both ancestors at once:\n * B's ProviderFactory (health TTL cache, priority fallback walk, media\n * dispatch) and A's singleton configureProvider (via createAI). Adds the\n * provider-neutral `chat`/`chatStream` text surface with full usage\n * propagation, and keeps B's ITextGenerator string facade so the ported\n * content services compile unchanged.\n */\nexport class ProviderFactory implements ITextGenerator {\n private readonly providers = new Map<string, AnyProvider>();\n private readonly healthCache = new Map<string, HealthCheckCache>();\n private readonly priority: ReadonlyArray<string>;\n private readonly fallbackEnabled: boolean;\n readonly defaultTier: TextTier;\n\n constructor(config: ProviderFactoryConfig = {}) {\n this.priority = config.priority ?? [];\n this.fallbackEnabled = config.fallbackEnabled ?? true;\n this.defaultTier = config.defaultTier ?? \"balanced\";\n }\n\n register(provider: AnyProvider): void {\n this.providers.set(provider.id, provider);\n }\n\n getProvider(id: string): AnyProvider | undefined {\n return this.providers.get(id);\n }\n\n getAllProviders(): AnyProvider[] {\n return Array.from(this.providers.values());\n }\n\n getByCapability(capability: ProviderCapability): AnyProvider[] {\n return this.getAllProviders().filter((provider) =>\n provider.capabilities.includes(capability),\n );\n }\n\n getTextProviders(): ITextProvider[] {\n return this.getAllProviders().filter(isTextProvider);\n }\n\n hasTextProvider(): boolean {\n return this.getByCapability(\"text\").length > 0;\n }\n\n /* ---------- neutral text surface ---------- */\n\n /**\n * Single-chat entry point: resolves a healthy text provider by priority,\n * injects the default tier when the request names neither model nor tier,\n * and walks the fallback chain on failure. Providers map tiers onto their\n * own models, so switching Groq→Anthropic is a config change.\n */\n async chat(request: TextRequest): Promise<GenerationResult> {\n const effective: TextRequest =\n request.model || request.tier ? request : { ...request, tier: this.defaultTier };\n return this.executeWithFallback(\"text\", (provider) =>\n (provider as ITextProvider).generate(effective),\n );\n }\n\n async chatStream(\n request: TextRequest,\n callbacks: StreamCallbacks,\n ): Promise<GenerationResult> {\n const effective: TextRequest =\n request.model || request.tier ? request : { ...request, tier: this.defaultTier };\n\n let lastError: unknown;\n // onError is withheld until every provider has failed — a successful\n // fallback would otherwise have already reported a spurious error.\n const attemptCallbacks: StreamCallbacks = {\n onChunk: callbacks.onChunk,\n onComplete: callbacks.onComplete,\n };\n\n const providers = this.getByCapability(\"text\");\n if (providers.length === 0) {\n throw this.noProviderError(\"text\");\n }\n\n const ordered = this.orderByPriority(providers);\n for (const provider of ordered) {\n if (!this.isProviderHealthy(provider.id)) continue;\n try {\n return await (provider as ITextProvider).stream(effective, attemptCallbacks);\n } catch (error) {\n lastError = error;\n this.markDegraded(provider.id);\n if (!this.fallbackEnabled) {\n callbacks.onError?.(error instanceof Error ? error : new Error(String(error)));\n throw error;\n }\n }\n }\n\n const failure = new AIError(\n AIErrorType.SERVER_ERROR,\n `All providers failed for capability 'text'`,\n lastError instanceof Error ? lastError : undefined,\n );\n callbacks.onError?.(lastError instanceof Error ? lastError : failure);\n throw failure;\n }\n\n /** AsyncGenerator adapter over chatStream — A's familiar consumption shape. */\n async *streamText(request: TextRequest): AsyncGenerator<string> {\n const queue: string[] = [];\n let wake: (() => void) | null = null;\n let finished = false;\n let failure: unknown;\n\n const notify = (): void => {\n const resolve = wake;\n wake = null;\n resolve?.();\n };\n\n const completion = this.chatStream(request, {\n onChunk: (chunk) => {\n queue.push(chunk);\n notify();\n },\n }).then(\n () => {\n finished = true;\n notify();\n },\n (error) => {\n failure = error;\n finished = true;\n notify();\n },\n );\n\n while (!finished || queue.length > 0) {\n if (queue.length === 0 && !finished) {\n await new Promise<void>((resolve) => {\n wake = resolve;\n });\n }\n while (queue.length > 0) {\n yield queue.shift() as string;\n }\n if (failure) throw failure;\n }\n await completion;\n }\n\n async generateJson<T>(\n request: StructuredTextRequest,\n ): Promise<StructuredGeneration<T>> {\n const effective: StructuredTextRequest =\n request.model || request.tier ? request : { ...request, tier: this.defaultTier };\n return this.executeWithFallback(\"text\", (provider) =>\n (provider as ITextProvider).generateStructured<T>(effective),\n );\n }\n\n /* ---------- content-layer string facade (ITextGenerator) ---------- */\n\n async generateText(prompt: string, options: TextGenerationOptions = {}): Promise<string> {\n const result = await this.chat({\n messages: [{ role: \"user\", content: prompt }],\n model: options.model,\n maxTokens: options.maxTokens,\n temperature: options.temperature,\n topP: options.topP,\n });\n return result.text;\n }\n\n generateTextStream(prompt: string, options: TextGenerationOptions = {}): AsyncGenerator<string> {\n return this.streamText({\n messages: [{ role: \"user\", content: prompt }],\n model: options.model,\n maxTokens: options.maxTokens,\n temperature: options.temperature,\n topP: options.topP,\n });\n }\n\n /* ---------- media surface ---------- */\n\n async generateImage(request: ImageGenerationRequest): Promise<GeneratedContent> {\n return this.executeWithFallback(\"image\", (provider) =>\n (provider as IMediaProvider).generateImage(request),\n );\n }\n\n async generateVideo(request: VideoGenerationRequest): Promise<GeneratedContent> {\n return this.executeWithFallback(\"video\", (provider) =>\n (provider as IMediaProvider).generateVideo(request),\n );\n }\n\n async imageToVideo(request: ImageToVideoRequest): Promise<GeneratedContent> {\n return this.executeWithFallback(\"video\", (provider) =>\n (provider as IMediaProvider).imageToVideo(request),\n );\n }\n\n async videoToVideo(request: VideoToVideoRequest): Promise<GeneratedContent> {\n return this.executeWithFallback(\"video\", (provider) =>\n (provider as IMediaProvider).videoToVideo(request),\n );\n }\n\n /* ---------- health ---------- */\n\n async checkProviderHealth(providerId: string, forceRefresh = false): Promise<ProviderHealth> {\n const provider = this.providers.get(providerId);\n if (!provider) {\n return \"unavailable\";\n }\n\n const cached = this.healthCache.get(providerId);\n const now = Date.now();\n const ttl = ProviderTimingConfig.HEALTH_CHECK_TTL_MS;\n\n if (!forceRefresh && cached && now - cached.timestamp < ttl) {\n return cached.health;\n }\n\n try {\n const health = await provider.healthCheck();\n this.healthCache.set(providerId, { health, timestamp: now });\n return health;\n } catch {\n this.healthCache.set(providerId, { health: \"unavailable\", timestamp: now });\n return \"unavailable\";\n }\n }\n\n isProviderHealthy(providerId: string): boolean {\n const cached = this.healthCache.get(providerId);\n if (!cached) {\n return true;\n }\n return cached.health === \"healthy\" || cached.health === \"degraded\";\n }\n\n async refreshAllHealth(): Promise<void> {\n await Promise.all(\n Array.from(this.providers.keys()).map((id) => this.checkProviderHealth(id)),\n );\n }\n\n /* ---------- internals ---------- */\n\n private async executeWithFallback<T>(\n capability: ProviderCapability,\n fn: (provider: AnyProvider) => Promise<T>,\n ): Promise<T> {\n const providers = this.getByCapability(capability);\n if (providers.length === 0) {\n throw this.noProviderError(capability);\n }\n\n let lastError: unknown;\n for (const provider of this.orderByPriority(providers)) {\n if (!this.isProviderHealthy(provider.id)) {\n continue;\n }\n\n try {\n return await fn(provider);\n } catch (error) {\n lastError = error;\n this.markDegraded(provider.id);\n if (!this.fallbackEnabled) {\n throw error;\n }\n }\n }\n\n throw new AIError(\n AIErrorType.SERVER_ERROR,\n `All providers failed for capability '${capability}'`,\n lastError instanceof Error ? lastError : undefined,\n );\n }\n\n private orderByPriority(providers: AnyProvider[]): AnyProvider[] {\n if (this.priority.length === 0) {\n return providers;\n }\n const ordered: AnyProvider[] = [];\n for (const providerId of this.priority) {\n const provider = providers.find((p) => p.id === providerId);\n if (provider) ordered.push(provider);\n }\n for (const provider of providers) {\n if (!this.priority.includes(provider.id)) {\n ordered.push(provider);\n }\n }\n return ordered;\n }\n\n private markDegraded(providerId: string): void {\n const cached = this.healthCache.get(providerId);\n if (cached) {\n this.healthCache.set(providerId, { health: \"degraded\", timestamp: cached.timestamp });\n }\n }\n\n private noProviderError(capability: ProviderCapability): AIError {\n return new AIError(\n AIErrorType.MISSING_CONFIG,\n `No provider registered for capability '${capability}' — create one with createAI() and include its config block`,\n );\n }\n}\n","\nconst BASE_36_RADIX = 36;\nconst DECIMAL_OFFSET = 2;\n\nexport function generateRandomBase36Suffix(\n length: number,\n random: () => number = Math.random,\n): string {\n if (length <= 0) return \"\";\n const raw = random().toString(BASE_36_RADIX).slice(DECIMAL_OFFSET);\n if (raw.length >= length) return raw.slice(0, length);\n\n let result = raw;\n while (result.length < length) {\n result += random().toString(BASE_36_RADIX).slice(DECIMAL_OFFSET);\n }\n return result.slice(0, length);\n}\n","\nexport const MESSAGE_ID_PREFIX = \"msg-\" as const;\nexport const CHAT_MESSAGE_ID_SUFFIX_LENGTH = 9;\nexport const CACHE_KEY_TYPE_COMPLETION = \"completion\" as const;\nexport const CACHE_KEY_TYPE_CHAT = \"chat\" as const;\nexport const CACHE_KEY_TYPE_RESPONSE = \"response\" as const;\nexport const SYSTEM_PROMPT_CACHE_PREFIX = \"system-prompt\" as const;\n\nexport const USER_ROLE = \"user\" as const;\nexport const ASSISTANT_ROLE = \"assistant\" as const;\nexport const SYSTEM_ROLE = \"system\" as const;\n\nexport const QUEUE_PRIORITY_USER_REQUEST = 10;\nexport const DEFAULT_RETRY_MAX_ATTEMPTS = 3;\nexport const DEFAULT_RETRY_INITIAL_DELAY_MS = 1000;\nexport const DEFAULT_RETRY_MAX_DELAY_MS = 10000;\nexport const DEFAULT_RETRY_BACKOFF_MULTIPLIER = 2;\nexport const DEFAULT_RETRY_JITTER_FACTOR = 0.1;\n","\nimport { generateRandomBase36Suffix } from \"../../core/calculations/random-base36-suffix\";\nimport {\n MESSAGE_ID_PREFIX,\n CHAT_MESSAGE_ID_SUFFIX_LENGTH,\n} from \"../../core/constants/identifier.constants\";\n\nconst ID_PART_DELIMITER = \"-\";\n\nexport class ChatIdGenerator {\n private counter = 0;\n private readonly randomLength: number;\n\n constructor(randomLength: number = CHAT_MESSAGE_ID_SUFFIX_LENGTH) {\n this.randomLength = randomLength;\n }\n\n next(sender: string): string {\n this.counter += 1;\n const random = generateRandomBase36Suffix(this.randomLength);\n return [\n MESSAGE_ID_PREFIX,\n Date.now(),\n sender,\n this.counter,\n random,\n ].join(ID_PART_DELIMITER);\n }\n}\n\nexport const chatIdGenerator = new ChatIdGenerator();\n","\nimport type { IMessageFormatter } from \"../interfaces\";\nimport type { ChatMessage } from \"../entities\";\nimport type { ChatMessage as CoreChatMessage } from \"../../core/types\";\nimport type { ChatIdGenerator } from \"./chat-id-generator\";\nimport { chatIdGenerator as defaultIdGenerator } from \"./chat-id-generator\";\nimport { ASSISTANT_ROLE, USER_ROLE } from \"../../core/constants/identifier.constants\";\n\nexport class MessageFormatter implements IMessageFormatter {\n constructor(private readonly idGenerator: ChatIdGenerator = defaultIdGenerator) {}\n\n /** Maps chat-domain history to neutral core messages; system senders are\n * dropped — the system prompt travels on the request's own slot. */\n toCoreMessages(messages: ReadonlyArray<ChatMessage>): CoreChatMessage[] {\n const coreMessages: CoreChatMessage[] = [];\n for (const message of messages) {\n if (message.sender === \"system\") continue;\n coreMessages.push({\n role: message.sender === \"user\" ? USER_ROLE : ASSISTANT_ROLE,\n content: message.content,\n });\n }\n return coreMessages;\n }\n\n toChatMessage(content: string, sender: ChatMessage[\"sender\"]): ChatMessage {\n return {\n id: this.idGenerator.next(sender),\n sender,\n content: content.trim(),\n timestamp: new Date().toISOString(),\n type: \"text\",\n };\n }\n}\n\nexport const messageFormatter = new MessageFormatter();\n","\nimport type { ChatConfig } from \"../entities\";\n\nexport interface SystemPromptStrategy {\n resolve(config: ChatConfig): string | undefined;\n}\n\nexport const DEFAULT_PROMPT_STRATEGY: SystemPromptStrategy = {\n resolve: (config) => {\n if (config.systemPrompt && config.systemPrompt.length > 0) {\n return config.systemPrompt;\n }\n return undefined;\n },\n};\n","\nimport type {\n IChatService,\n SystemPromptStrategy,\n} from \"../interfaces\";\nimport type {\n ChatMessage,\n ChatConfig,\n ChatConversation,\n SendMessageInput,\n SendMessageResult,\n IChatStorage,\n ChatTokenUsage,\n} from \"../entities\";\nimport type { GenerationResult, StreamCallbacks, TextRequest } from \"../../core/types\";\nimport { AIError, AIErrorType } from \"../../core/errors\";\nimport type { ITextProvider } from \"../../providers/base/provider.types\";\nimport { ProviderFactory } from \"../../providers/factory/provider.factory\";\nimport { messageFormatter } from \"../utils/message-formatter\";\nimport { DEFAULT_PROMPT_STRATEGY } from \"../utils/prompt-strategy\";\n\nconst DEFAULT_CONFIG: ChatConfig = {\n temperature: 0.8,\n maxTokens: 500,\n};\n\n/**\n * Conversation engine over the neutral text surface. Accepts either a\n * single ITextProvider or a ProviderFactory (which brings tier defaults,\n * health checks, and fallback across providers). Model choice is tier-based:\n * `config.tier ?? provider default` — no hardcoded model names anywhere.\n */\nexport class ChatService implements IChatService {\n private config: ChatConfig = DEFAULT_CONFIG;\n private promptStrategy: SystemPromptStrategy = DEFAULT_PROMPT_STRATEGY;\n private storage: IChatStorage | null = null;\n\n constructor(\n private readonly engine: ITextProvider | ProviderFactory,\n ) {}\n\n initialize(config: ChatConfig): void {\n this.config = { ...DEFAULT_CONFIG, ...config };\n }\n\n updateConfig(config: Partial<ChatConfig>): void {\n this.config = { ...this.config, ...config };\n }\n\n setPromptStrategy(strategy: SystemPromptStrategy): void {\n this.promptStrategy = strategy;\n }\n\n setStorage(storage: IChatStorage): void {\n this.storage = storage;\n }\n\n async getConversation(conversationId: string): Promise<ChatConversation | null> {\n const storage = this.requireStorage();\n const messages = await storage.getMessages(conversationId);\n if (messages.length === 0) return null;\n const last = messages[messages.length - 1];\n const first = messages[0];\n const companionId = String(first.metadata?.[\"companionId\"] ?? \"unknown\");\n const companionName = String(first.metadata?.[\"companionName\"] ?? \"Unknown\");\n return {\n id: conversationId,\n companionId,\n companionName,\n lastMessage: last,\n messageCount: messages.length,\n updatedAt: last.timestamp,\n };\n }\n\n async getConversations(): Promise<ChatConversation[]> {\n return [];\n }\n\n async sendMessage(input: SendMessageInput): Promise<SendMessageResult> {\n const userMessage: ChatMessage = {\n ...messageFormatter.toChatMessage(input.text, \"user\"),\n type: input.type ?? \"text\",\n ...(input.imageUrl !== undefined ? { imageUrl: input.imageUrl } : {}),\n };\n\n const aiResponse = await this.generateAIResponse(\n input.companionId,\n input.text,\n [],\n );\n\n return { userMessage, aiResponse };\n }\n\n async generateAIResponse(\n companionId: string,\n userMessage: string,\n context: ReadonlyArray<ChatMessage> = [],\n ): Promise<ChatMessage> {\n const result = await this.run({\n ...this.buildRequest(userMessage, context),\n });\n\n return {\n ...messageFormatter.toChatMessage(result.text, \"assistant\"),\n metadata: {\n companionId,\n model: result.model,\n usage: {\n input_tokens: result.usage?.inputTokens,\n output_tokens: result.usage?.outputTokens,\n total_tokens: result.usage?.totalTokens,\n },\n finishReason: result.finishReason,\n },\n };\n }\n\n async generateStreamingResponse(\n userMessage: string,\n context: ReadonlyArray<ChatMessage>,\n onChunk: (chunk: string) => void,\n ): Promise<string> {\n const request = this.buildRequest(userMessage, context);\n const result = await this.runStream(request, { onChunk });\n return result.text;\n }\n\n private buildRequest(\n userMessage: string,\n context: ReadonlyArray<ChatMessage>,\n ): TextRequest {\n const messages = messageFormatter.toCoreMessages(context);\n messages.push({ role: \"user\", content: userMessage });\n return {\n messages,\n systemPrompt: this.resolveSystemPrompt(),\n model: this.config.model,\n tier: this.config.tier,\n temperature: this.config.temperature,\n maxTokens: this.config.maxTokens,\n };\n }\n\n private resolveSystemPrompt(): string | undefined {\n const prompt = this.promptStrategy.resolve(this.config);\n return prompt && prompt.length > 0 ? prompt : undefined;\n }\n\n private async run(request: TextRequest): Promise<GenerationResult> {\n if (this.engine instanceof ProviderFactory) {\n return this.engine.chat(request);\n }\n return this.engine.generate(request);\n }\n\n private async runStream(\n request: TextRequest,\n callbacks: Pick<StreamCallbacks, \"onChunk\">,\n ): Promise<GenerationResult> {\n if (this.engine instanceof ProviderFactory) {\n return this.engine.chatStream(request, callbacks);\n }\n return this.engine.stream(request, callbacks);\n }\n\n private requireStorage(): IChatStorage {\n if (!this.storage) {\n throw new AIError(\n AIErrorType.MISSING_CONFIG,\n \"ChatService.getConversation requires setStorage() to be called first.\",\n );\n }\n return this.storage;\n }\n}\n\nexport function extractTokenUsage(message: ChatMessage): ChatTokenUsage | null {\n const meta = message.metadata;\n if (!meta) return null;\n const usage = meta[\"usage\"];\n if (!usage || typeof usage !== \"object\") return null;\n const u = usage as Record<string, unknown>;\n const inputTokens = readNumber(u, [\"input_tokens\", \"prompt_tokens\"]);\n const outputTokens = readNumber(u, [\"output_tokens\", \"completion_tokens\"]);\n const totalTokens = readNumber(u, [\"total_tokens\"]);\n if (inputTokens === null || outputTokens === null || totalTokens === null) {\n return null;\n }\n return {\n promptTokens: inputTokens,\n completionTokens: outputTokens,\n totalTokens,\n };\n}\n\nfunction readNumber(\n source: Record<string, unknown>,\n keys: ReadonlyArray<string>,\n): number | null {\n for (const key of keys) {\n const value = source[key];\n if (typeof value === \"number\") return value;\n }\n return null;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/core/errors/ai-error-types.ts","../../src/core/errors/ai-error.ts","../../src/providers/base/provider.types.ts","../../src/content/domain/limits/ProviderTimingConfig.ts","../../src/providers/factory/provider.factory.ts","../../src/core/calculations/random-base36-suffix.ts","../../src/core/constants/identifier.constants.ts","../../src/chat/utils/chat-id-generator.ts","../../src/chat/utils/message-formatter.ts","../../src/chat/utils/prompt-strategy.ts","../../src/chat/services/chat.service.ts"],"names":["AIErrorType"],"mappings":"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","file":"index.cjs","sourcesContent":["\nexport enum AIErrorType {\n INVALID_API_KEY = \"INVALID_API_KEY\",\n MISSING_CONFIG = \"MISSING_CONFIG\",\n NETWORK_ERROR = \"NETWORK_ERROR\",\n ABORT_ERROR = \"ABORT_ERROR\",\n RATE_LIMIT_ERROR = \"RATE_LIMIT_ERROR\",\n SERVER_ERROR = \"SERVER_ERROR\",\n CLIENT_ERROR = \"CLIENT_ERROR\",\n UNKNOWN_ERROR = \"UNKNOWN_ERROR\",\n}\n\nexport const USER_FRIENDLY_ERROR_MESSAGES: Readonly<Record<AIErrorType, string>> = {\n [AIErrorType.INVALID_API_KEY]: \"Please check your API key and try again.\",\n [AIErrorType.MISSING_CONFIG]: \"The provider is not configured. Please create a provider with createAI first.\",\n [AIErrorType.NETWORK_ERROR]: \"Network error. Please check your connection and try again.\",\n [AIErrorType.ABORT_ERROR]: \"Request was cancelled.\",\n [AIErrorType.RATE_LIMIT_ERROR]: \"You've reached the rate limit. Please wait a moment and try again.\",\n [AIErrorType.SERVER_ERROR]: \"The AI service is temporarily unavailable. Please try again later.\",\n [AIErrorType.CLIENT_ERROR]: \"The request was invalid. Please check your input and try again.\",\n [AIErrorType.UNKNOWN_ERROR]: \"An unexpected error occurred. Please try again.\",\n};\n","\nimport { AIErrorType } from \"./ai-error-types\";\n\nexport interface AIErrorMetadata {\n readonly status?: number;\n readonly url?: string;\n readonly [key: string]: unknown;\n}\n\nconst KNOWN_ERROR_TYPES = new Set<string>(Object.values(AIErrorType));\n\nfunction mapCodeToType(code: string): AIErrorType {\n switch (code) {\n case \"VALIDATION_ERROR\":\n case \"CLIENT_ERROR\":\n return AIErrorType.CLIENT_ERROR;\n case \"INVALID_API_KEY\":\n return AIErrorType.INVALID_API_KEY;\n case \"MISSING_CONFIG\":\n case \"PROVIDER_UNAVAILABLE\":\n return AIErrorType.MISSING_CONFIG;\n case \"PROVIDER_QUOTA_EXHAUSTED\":\n case \"RATE_LIMIT_ERROR\":\n return AIErrorType.RATE_LIMIT_ERROR;\n case \"NETWORK_ERROR\":\n case \"TIMEOUT\":\n return AIErrorType.NETWORK_ERROR;\n case \"ABORT_ERROR\":\n case \"ABORTED\":\n return AIErrorType.ABORT_ERROR;\n case \"SERVER_ERROR\":\n case \"PROVIDER_ERROR\":\n case \"NO_RESULT\":\n return AIErrorType.SERVER_ERROR;\n default:\n return AIErrorType.UNKNOWN_ERROR;\n }\n}\n\nfunction mapMessageToCode(message: string, fallback: string = \"UNKNOWN\"): string {\n const lower = message.toLowerCase();\n if (lower.includes(\"validation\")) return \"VALIDATION_ERROR\";\n if (lower.includes(\"quota\")) return \"PROVIDER_QUOTA_EXHAUSTED\";\n if (lower.includes(\"unavailable\")) return \"PROVIDER_UNAVAILABLE\";\n if (lower.includes(\"timeout\") || lower.includes(\"aborted\")) {\n return lower.includes(\"aborted\") ? \"ABORTED\" : \"TIMEOUT\";\n }\n if (lower.includes(\"parse\") || lower.includes(\"json\")) return \"PARSE_ERROR\";\n if (lower.includes(\"no result\")) return \"NO_RESULT\";\n if (lower.includes(\"network\") || lower.includes(\"fetch\")) return \"NETWORK_ERROR\";\n return fallback;\n}\n\nexport class AIError extends Error {\n public readonly type: AIErrorType;\n public readonly code: string;\n public readonly cause?: unknown;\n public readonly metadata: AIErrorMetadata;\n\n constructor(\n typeOrMessage: AIErrorType | string,\n messageOrCode?: string,\n cause?: unknown,\n metadata: AIErrorMetadata = {},\n ) {\n let effectiveType: AIErrorType;\n let effectiveMessage: string;\n let effectiveCode: string;\n\n if (KNOWN_ERROR_TYPES.has(typeOrMessage)) {\n effectiveType = typeOrMessage as AIErrorType;\n effectiveMessage = messageOrCode ?? \"\";\n effectiveCode = effectiveType;\n } else {\n effectiveMessage = typeOrMessage;\n effectiveCode = messageOrCode ?? \"UNKNOWN\";\n effectiveType = mapCodeToType(effectiveCode);\n }\n\n super(effectiveMessage);\n this.name = \"AIError\";\n this.type = effectiveType;\n this.code = effectiveCode;\n this.cause = cause;\n this.metadata = metadata;\n }\n\n static from(error: unknown, fallbackCode: string = \"UNKNOWN\"): AIError {\n if (error instanceof AIError) return error;\n if (error instanceof Error) {\n const code = mapMessageToCode(error.message, fallbackCode);\n return new AIError(error.message, code, error);\n }\n return new AIError(String(error), fallbackCode, error);\n }\n\n override toString(): string {\n const statusPart =\n typeof this.metadata.status === \"number\" ? ` (HTTP ${this.metadata.status})` : \"\";\n return `${this.name} [${this.type}]: ${this.message}${statusPart}`;\n }\n\n toJSON(): {\n name: string;\n type: AIErrorType;\n code: string;\n message: string;\n metadata: AIErrorMetadata;\n } {\n return {\n name: this.name,\n type: this.type,\n code: this.code,\n message: this.message,\n metadata: this.metadata,\n };\n }\n}\n","\nimport type {\n GenerationResult,\n ProviderHealth,\n StreamCallbacks,\n StructuredGeneration,\n StructuredTextRequest,\n TextRequest,\n TextTier,\n} from \"../../core/types\";\nimport type {\n GeneratedContent,\n ImageGenerationRequest,\n ImageToVideoRequest,\n TextGenerationRequest,\n VideoGenerationRequest,\n VideoToVideoRequest,\n} from \"../../content/domain/config/ProviderConfig\";\n\n/**\n * What a provider can serve. Replaces the old single `'multimodal'` type flag:\n * a provider declares exactly the capabilities it implements, and the factory\n * walks providers by capability when routing or failing over.\n */\nexport type ProviderCapability = \"text\" | \"image\" | \"video\";\n\n/** Cost estimation input — any generation request shape the fleet knows. */\nexport type CostEstimateRequest =\n | TextGenerationRequest\n | ImageGenerationRequest\n | VideoGenerationRequest;\n\nexport interface IProviderBase {\n readonly id: string;\n readonly name: string;\n readonly capabilities: ReadonlyArray<ProviderCapability>;\n healthCheck(): Promise<ProviderHealth>;\n estimateCost(request: CostEstimateRequest): Promise<number>;\n}\n\n/**\n * A provider that can turn conversations into text. This is the surface the\n * factory's `chat`/`chatStream` walk; model choice per quality tier is the\n * provider's own business (each maps neutral tiers onto its catalogue).\n */\nexport interface ITextProvider extends IProviderBase {\n generate(request: TextRequest): Promise<GenerationResult>;\n generateStructured<T>(request: StructuredTextRequest): Promise<StructuredGeneration<T>>;\n stream(request: TextRequest, callbacks: StreamCallbacks): Promise<GenerationResult>;\n resolveModel(tier: TextTier): string;\n}\n\n/**\n * A provider that generates media. Kept as B's media surface — image/video\n * request and result shapes are already provider-neutral.\n */\nexport interface IMediaProvider extends IProviderBase {\n generateImage(request: ImageGenerationRequest): Promise<GeneratedContent>;\n generateVideo(request: VideoGenerationRequest): Promise<GeneratedContent>;\n imageToVideo(request: ImageToVideoRequest): Promise<GeneratedContent>;\n videoToVideo(request: VideoToVideoRequest): Promise<GeneratedContent>;\n}\n\nexport type AnyProvider = ITextProvider | IMediaProvider;\n\nexport function isTextProvider(provider: AnyProvider): provider is ITextProvider {\n return provider.capabilities.includes(\"text\");\n}\n\nexport function isMediaProvider(provider: AnyProvider): provider is IMediaProvider {\n return provider.capabilities.includes(\"image\") || provider.capabilities.includes(\"video\");\n}\n","\nexport const ProviderTimingConfig = {\n DEFAULT_TIMEOUT_MS: 30_000,\n DEFAULT_RETRY_ATTEMPTS: 3,\n\n FAL_TIMEOUT_MS: 120_000,\n FAL_RETRY_ATTEMPTS: 2,\n\n GEMINI_TIMEOUT_MS: 60_000,\n GEMINI_RETRY_ATTEMPTS: 3,\n\n GROQ_TIMEOUT_MS: 30_000,\n GROQ_RETRY_ATTEMPTS: 3,\n\n HEALTH_CHECK_TTL_MS: 5 * 60 * 1000,\n\n RETRY_BACKOFF_BASE_MS: 1_000,\n} as const;\n","\nimport type {\n GenerationResult,\n ProviderHealth,\n StreamCallbacks,\n StructuredGeneration,\n StructuredTextRequest,\n TextRequest,\n TextTier,\n} from \"../../core/types\";\nimport { AIError, AIErrorType } from \"../../core/errors\";\nimport type {\n AnyProvider,\n IMediaProvider,\n ITextProvider,\n ProviderCapability,\n} from \"../base/provider.types\";\nimport { isTextProvider } from \"../base/provider.types\";\nimport type {\n GeneratedContent,\n ImageGenerationRequest,\n ImageToVideoRequest,\n VideoGenerationRequest,\n VideoToVideoRequest,\n} from \"../../content/domain/config/ProviderConfig\";\nimport type {\n ITextGenerator,\n TextGenerationOptions,\n} from \"../../content/domain/interfaces/ITextGenerator\";\nimport { ProviderTimingConfig } from \"../../content/domain/limits/ProviderTimingConfig\";\n\nexport interface ProviderFactoryConfig {\n /** Provider ids in preference order; unlisted providers follow in registration order. */\n priority?: ReadonlyArray<string>;\n fallbackEnabled?: boolean;\n /** Tier used when a request names neither a model nor a tier. */\n defaultTier?: TextTier;\n}\n\ninterface HealthCheckCache {\n health: ProviderHealth;\n timestamp: number;\n}\n\n/**\n * Composition-aware registry and router. Replaces both ancestors at once:\n * B's ProviderFactory (health TTL cache, priority fallback walk, media\n * dispatch) and A's singleton configureProvider (via createAI). Adds the\n * provider-neutral `chat`/`chatStream` text surface with full usage\n * propagation, and keeps B's ITextGenerator string facade so the ported\n * content services compile unchanged.\n */\nexport class ProviderFactory implements ITextGenerator {\n private readonly providers = new Map<string, AnyProvider>();\n private readonly healthCache = new Map<string, HealthCheckCache>();\n private readonly priority: ReadonlyArray<string>;\n private readonly fallbackEnabled: boolean;\n readonly defaultTier: TextTier;\n\n constructor(config: ProviderFactoryConfig = {}) {\n this.priority = config.priority ?? [];\n this.fallbackEnabled = config.fallbackEnabled ?? true;\n this.defaultTier = config.defaultTier ?? \"balanced\";\n }\n\n register(provider: AnyProvider): void {\n this.providers.set(provider.id, provider);\n }\n\n getProvider(id: string): AnyProvider | undefined {\n return this.providers.get(id);\n }\n\n getAllProviders(): AnyProvider[] {\n return Array.from(this.providers.values());\n }\n\n getByCapability(capability: ProviderCapability): AnyProvider[] {\n return this.getAllProviders().filter((provider) =>\n provider.capabilities.includes(capability),\n );\n }\n\n getTextProviders(): ITextProvider[] {\n return this.getAllProviders().filter(isTextProvider);\n }\n\n hasTextProvider(): boolean {\n return this.getByCapability(\"text\").length > 0;\n }\n\n /* ---------- neutral text surface ---------- */\n\n /**\n * Single-chat entry point: resolves a healthy text provider by priority,\n * injects the default tier when the request names neither model nor tier,\n * and walks the fallback chain on failure. Providers map tiers onto their\n * own models, so switching Groq→Anthropic is a config change.\n */\n async chat(request: TextRequest): Promise<GenerationResult> {\n const effective: TextRequest =\n request.model || request.tier ? request : { ...request, tier: this.defaultTier };\n return this.executeWithFallback(\"text\", (provider) =>\n (provider as ITextProvider).generate(effective),\n );\n }\n\n async chatStream(\n request: TextRequest,\n callbacks: StreamCallbacks,\n ): Promise<GenerationResult> {\n const effective: TextRequest =\n request.model || request.tier ? request : { ...request, tier: this.defaultTier };\n\n let lastError: unknown;\n // onError is withheld until every provider has failed — a successful\n // fallback would otherwise have already reported a spurious error.\n const attemptCallbacks: StreamCallbacks = {\n onChunk: callbacks.onChunk,\n onComplete: callbacks.onComplete,\n };\n\n const providers = this.getByCapability(\"text\");\n if (providers.length === 0) {\n throw this.noProviderError(\"text\");\n }\n\n const ordered = this.orderByPriority(providers);\n for (const provider of ordered) {\n if (!this.isProviderHealthy(provider.id)) continue;\n try {\n return await (provider as ITextProvider).stream(effective, attemptCallbacks);\n } catch (error) {\n lastError = error;\n this.markDegraded(provider.id);\n if (!this.fallbackEnabled) {\n callbacks.onError?.(error instanceof Error ? error : new Error(String(error)));\n throw error;\n }\n }\n }\n\n const failure = new AIError(\n AIErrorType.SERVER_ERROR,\n `All providers failed for capability 'text'`,\n lastError instanceof Error ? lastError : undefined,\n );\n callbacks.onError?.(lastError instanceof Error ? lastError : failure);\n throw failure;\n }\n\n /** AsyncGenerator adapter over chatStream — A's familiar consumption shape. */\n async *streamText(request: TextRequest): AsyncGenerator<string> {\n const queue: string[] = [];\n let wake: (() => void) | null = null;\n let finished = false;\n let failure: unknown;\n\n const controller = new AbortController();\n const onAbort = () => controller.abort();\n request.signal?.addEventListener(\"abort\", onAbort);\n const effectiveRequest = { ...request, signal: controller.signal };\n\n const notify = (): void => {\n const resolve = wake;\n wake = null;\n resolve?.();\n };\n\n const completion = this.chatStream(effectiveRequest, {\n onChunk: (chunk) => {\n queue.push(chunk);\n notify();\n },\n }).then(\n () => {\n finished = true;\n notify();\n },\n (error) => {\n failure = error;\n finished = true;\n notify();\n },\n );\n\n try {\n while (!finished || queue.length > 0) {\n if (queue.length === 0 && !finished) {\n await new Promise<void>((resolve) => {\n wake = resolve;\n });\n }\n while (queue.length > 0) {\n yield queue.shift() as string;\n }\n if (failure) throw failure;\n }\n await completion;\n } finally {\n controller.abort();\n request.signal?.removeEventListener(\"abort\", onAbort);\n }\n }\n\n async generateJson<T>(\n request: StructuredTextRequest,\n ): Promise<StructuredGeneration<T>> {\n const effective: StructuredTextRequest =\n request.model || request.tier ? request : { ...request, tier: this.defaultTier };\n return this.executeWithFallback(\"text\", (provider) =>\n (provider as ITextProvider).generateStructured<T>(effective),\n );\n }\n\n /* ---------- content-layer string facade (ITextGenerator) ---------- */\n\n async generateText(prompt: string, options: TextGenerationOptions = {}): Promise<string> {\n const result = await this.chat({\n messages: [{ role: \"user\", content: prompt }],\n model: options.model,\n maxTokens: options.maxTokens,\n temperature: options.temperature,\n topP: options.topP,\n });\n return result.text;\n }\n\n generateTextStream(prompt: string, options: TextGenerationOptions = {}): AsyncGenerator<string> {\n return this.streamText({\n messages: [{ role: \"user\", content: prompt }],\n model: options.model,\n maxTokens: options.maxTokens,\n temperature: options.temperature,\n topP: options.topP,\n });\n }\n\n /* ---------- media surface ---------- */\n\n async generateImage(request: ImageGenerationRequest): Promise<GeneratedContent> {\n return this.executeWithFallback(\"image\", (provider) =>\n (provider as IMediaProvider).generateImage(request),\n );\n }\n\n async generateVideo(request: VideoGenerationRequest): Promise<GeneratedContent> {\n return this.executeWithFallback(\"video\", (provider) =>\n (provider as IMediaProvider).generateVideo(request),\n );\n }\n\n async imageToVideo(request: ImageToVideoRequest): Promise<GeneratedContent> {\n return this.executeWithFallback(\"video\", (provider) =>\n (provider as IMediaProvider).imageToVideo(request),\n );\n }\n\n async videoToVideo(request: VideoToVideoRequest): Promise<GeneratedContent> {\n return this.executeWithFallback(\"video\", (provider) =>\n (provider as IMediaProvider).videoToVideo(request),\n );\n }\n\n /* ---------- health ---------- */\n\n async checkProviderHealth(providerId: string, forceRefresh = false): Promise<ProviderHealth> {\n const provider = this.providers.get(providerId);\n if (!provider) {\n return \"unavailable\";\n }\n\n const cached = this.healthCache.get(providerId);\n const now = Date.now();\n const ttl = ProviderTimingConfig.HEALTH_CHECK_TTL_MS;\n\n if (!forceRefresh && cached && now - cached.timestamp < ttl) {\n return cached.health;\n }\n\n try {\n const health = await provider.healthCheck();\n this.healthCache.set(providerId, { health, timestamp: now });\n return health;\n } catch {\n this.healthCache.set(providerId, { health: \"unavailable\", timestamp: now });\n return \"unavailable\";\n }\n }\n\n isProviderHealthy(providerId: string): boolean {\n const cached = this.healthCache.get(providerId);\n if (!cached) {\n return true;\n }\n return cached.health === \"healthy\" || cached.health === \"degraded\";\n }\n\n async refreshAllHealth(): Promise<void> {\n await Promise.all(\n Array.from(this.providers.keys()).map((id) => this.checkProviderHealth(id)),\n );\n }\n\n /* ---------- internals ---------- */\n\n private async executeWithFallback<T>(\n capability: ProviderCapability,\n fn: (provider: AnyProvider) => Promise<T>,\n ): Promise<T> {\n const providers = this.getByCapability(capability);\n if (providers.length === 0) {\n throw this.noProviderError(capability);\n }\n\n let lastError: unknown;\n for (const provider of this.orderByPriority(providers)) {\n if (!this.isProviderHealthy(provider.id)) {\n continue;\n }\n\n try {\n return await fn(provider);\n } catch (error) {\n lastError = error;\n this.markDegraded(provider.id);\n if (!this.fallbackEnabled) {\n throw error;\n }\n }\n }\n\n throw new AIError(\n AIErrorType.SERVER_ERROR,\n `All providers failed for capability '${capability}'`,\n lastError instanceof Error ? lastError : undefined,\n );\n }\n\n private orderByPriority(providers: AnyProvider[]): AnyProvider[] {\n if (this.priority.length === 0) {\n return providers;\n }\n const ordered: AnyProvider[] = [];\n for (const providerId of this.priority) {\n const provider = providers.find((p) => p.id === providerId);\n if (provider) ordered.push(provider);\n }\n for (const provider of providers) {\n if (!this.priority.includes(provider.id)) {\n ordered.push(provider);\n }\n }\n return ordered;\n }\n\n private markDegraded(providerId: string): void {\n const cached = this.healthCache.get(providerId);\n if (cached) {\n this.healthCache.set(providerId, { health: \"degraded\", timestamp: cached.timestamp });\n }\n }\n\n private noProviderError(capability: ProviderCapability): AIError {\n return new AIError(\n AIErrorType.MISSING_CONFIG,\n `No provider registered for capability '${capability}' — create one with createAI() and include its config block`,\n );\n }\n}\n","\nconst BASE_36_RADIX = 36;\nconst DECIMAL_OFFSET = 2;\n\nexport function generateRandomBase36Suffix(\n length: number,\n random: () => number = Math.random,\n): string {\n if (length <= 0) return \"\";\n const raw = random().toString(BASE_36_RADIX).slice(DECIMAL_OFFSET);\n if (raw.length >= length) return raw.slice(0, length);\n\n let result = raw;\n while (result.length < length) {\n result += random().toString(BASE_36_RADIX).slice(DECIMAL_OFFSET);\n }\n return result.slice(0, length);\n}\n","\nexport const MESSAGE_ID_PREFIX = \"msg-\" as const;\nexport const CHAT_MESSAGE_ID_SUFFIX_LENGTH = 9;\nexport const CACHE_KEY_TYPE_COMPLETION = \"completion\" as const;\nexport const CACHE_KEY_TYPE_CHAT = \"chat\" as const;\nexport const CACHE_KEY_TYPE_RESPONSE = \"response\" as const;\nexport const SYSTEM_PROMPT_CACHE_PREFIX = \"system-prompt\" as const;\n\nexport const USER_ROLE = \"user\" as const;\nexport const ASSISTANT_ROLE = \"assistant\" as const;\nexport const SYSTEM_ROLE = \"system\" as const;\n\nexport const QUEUE_PRIORITY_USER_REQUEST = 10;\nexport const DEFAULT_RETRY_MAX_ATTEMPTS = 3;\nexport const DEFAULT_RETRY_INITIAL_DELAY_MS = 1000;\nexport const DEFAULT_RETRY_MAX_DELAY_MS = 10000;\nexport const DEFAULT_RETRY_BACKOFF_MULTIPLIER = 2;\nexport const DEFAULT_RETRY_JITTER_FACTOR = 0.1;\n","\nimport { generateRandomBase36Suffix } from \"../../core/calculations/random-base36-suffix\";\nimport {\n MESSAGE_ID_PREFIX,\n CHAT_MESSAGE_ID_SUFFIX_LENGTH,\n} from \"../../core/constants/identifier.constants\";\n\nconst ID_PART_DELIMITER = \"-\";\n\nexport class ChatIdGenerator {\n private counter = 0;\n private readonly randomLength: number;\n\n constructor(randomLength: number = CHAT_MESSAGE_ID_SUFFIX_LENGTH) {\n this.randomLength = randomLength;\n }\n\n next(sender: string): string {\n this.counter += 1;\n const random = generateRandomBase36Suffix(this.randomLength);\n return [\n MESSAGE_ID_PREFIX,\n Date.now(),\n sender,\n this.counter,\n random,\n ].join(ID_PART_DELIMITER);\n }\n}\n\nexport const chatIdGenerator = new ChatIdGenerator();\n","\nimport type { IMessageFormatter } from \"../interfaces\";\nimport type { ChatMessage } from \"../entities\";\nimport type { ChatMessage as CoreChatMessage } from \"../../core/types\";\nimport type { ChatIdGenerator } from \"./chat-id-generator\";\nimport { chatIdGenerator as defaultIdGenerator } from \"./chat-id-generator\";\nimport { ASSISTANT_ROLE, USER_ROLE } from \"../../core/constants/identifier.constants\";\n\nexport class MessageFormatter implements IMessageFormatter {\n constructor(private readonly idGenerator: ChatIdGenerator = defaultIdGenerator) {}\n\n /** Maps chat-domain history to neutral core messages; system senders are\n * dropped — the system prompt travels on the request's own slot. */\n toCoreMessages(messages: ReadonlyArray<ChatMessage>): CoreChatMessage[] {\n const coreMessages: CoreChatMessage[] = [];\n for (const message of messages) {\n if (message.sender === \"system\") continue;\n coreMessages.push({\n role: message.sender === \"user\" ? USER_ROLE : ASSISTANT_ROLE,\n content: message.content,\n });\n }\n return coreMessages;\n }\n\n toChatMessage(content: string, sender: ChatMessage[\"sender\"]): ChatMessage {\n return {\n id: this.idGenerator.next(sender),\n sender,\n content: content.trim(),\n timestamp: new Date().toISOString(),\n type: \"text\",\n };\n }\n}\n\nexport const messageFormatter = new MessageFormatter();\n","\nimport type { ChatConfig } from \"../entities\";\n\nexport interface SystemPromptStrategy {\n resolve(config: ChatConfig): string | undefined;\n}\n\nexport const DEFAULT_PROMPT_STRATEGY: SystemPromptStrategy = {\n resolve: (config) => {\n if (config.systemPrompt && config.systemPrompt.length > 0) {\n return config.systemPrompt;\n }\n return undefined;\n },\n};\n","\nimport type {\n IChatService,\n SystemPromptStrategy,\n} from \"../interfaces\";\nimport type {\n ChatMessage,\n ChatConfig,\n ChatConversation,\n SendMessageInput,\n SendMessageResult,\n IChatStorage,\n ChatTokenUsage,\n} from \"../entities\";\nimport type { GenerationResult, StreamCallbacks, TextRequest } from \"../../core/types\";\nimport { AIError, AIErrorType } from \"../../core/errors\";\nimport type { ITextProvider } from \"../../providers/base/provider.types\";\nimport { ProviderFactory } from \"../../providers/factory/provider.factory\";\nimport { messageFormatter } from \"../utils/message-formatter\";\nimport { DEFAULT_PROMPT_STRATEGY } from \"../utils/prompt-strategy\";\n\nconst DEFAULT_CONFIG: ChatConfig = {\n temperature: 0.8,\n maxTokens: 500,\n};\n\n/**\n * Conversation engine over the neutral text surface. Accepts either a\n * single ITextProvider or a ProviderFactory (which brings tier defaults,\n * health checks, and fallback across providers). Model choice is tier-based:\n * `config.tier ?? provider default` — no hardcoded model names anywhere.\n */\nexport class ChatService implements IChatService {\n private config: ChatConfig = DEFAULT_CONFIG;\n private promptStrategy: SystemPromptStrategy = DEFAULT_PROMPT_STRATEGY;\n private storage: IChatStorage | null = null;\n\n constructor(\n private readonly engine: ITextProvider | ProviderFactory,\n ) {}\n\n initialize(config: ChatConfig): void {\n this.config = { ...DEFAULT_CONFIG, ...config };\n }\n\n updateConfig(config: Partial<ChatConfig>): void {\n this.config = { ...this.config, ...config };\n }\n\n setPromptStrategy(strategy: SystemPromptStrategy): void {\n this.promptStrategy = strategy;\n }\n\n setStorage(storage: IChatStorage): void {\n this.storage = storage;\n }\n\n async getConversation(conversationId: string): Promise<ChatConversation | null> {\n const storage = this.requireStorage();\n const messages = await storage.getMessages(conversationId);\n if (messages.length === 0) return null;\n const last = messages[messages.length - 1];\n const first = messages[0];\n const companionId = String(first.metadata?.[\"companionId\"] ?? \"unknown\");\n const companionName = String(first.metadata?.[\"companionName\"] ?? \"Unknown\");\n return {\n id: conversationId,\n companionId,\n companionName,\n lastMessage: last,\n messageCount: messages.length,\n updatedAt: last.timestamp,\n };\n }\n\n async getConversations(): Promise<ChatConversation[]> {\n if (\n this.storage &&\n \"getConversations\" in this.storage &&\n typeof (this.storage as unknown as { getConversations: () => Promise<ChatConversation[]> }).getConversations === \"function\"\n ) {\n return (this.storage as unknown as { getConversations: () => Promise<ChatConversation[]> }).getConversations();\n }\n return [];\n }\n\n async sendMessage(input: SendMessageInput, signal?: AbortSignal): Promise<SendMessageResult> {\n const userMessage: ChatMessage = {\n ...messageFormatter.toChatMessage(input.text, \"user\"),\n type: input.type ?? \"text\",\n ...(input.imageUrl !== undefined ? { imageUrl: input.imageUrl } : {}),\n };\n\n const aiResponse = await this.generateAIResponse(\n input.companionId,\n input.text,\n [],\n signal,\n );\n\n return { userMessage, aiResponse };\n }\n\n async generateAIResponse(\n companionId: string,\n userMessage: string,\n context: ReadonlyArray<ChatMessage> = [],\n signal?: AbortSignal,\n ): Promise<ChatMessage> {\n const result = await this.run({\n ...this.buildRequest(userMessage, context, signal),\n });\n\n return {\n ...messageFormatter.toChatMessage(result.text, \"assistant\"),\n metadata: {\n companionId,\n model: result.model,\n usage: {\n input_tokens: result.usage?.inputTokens,\n output_tokens: result.usage?.outputTokens,\n total_tokens: result.usage?.totalTokens,\n },\n finishReason: result.finishReason,\n },\n };\n }\n\n async generateStreamingResponse(\n userMessage: string,\n context: ReadonlyArray<ChatMessage>,\n onChunk: (chunk: string) => void,\n signal?: AbortSignal,\n ): Promise<string> {\n const request = this.buildRequest(userMessage, context, signal);\n const result = await this.runStream(request, { onChunk });\n return result.text;\n }\n\n private buildRequest(\n userMessage: string,\n context: ReadonlyArray<ChatMessage>,\n signal?: AbortSignal,\n ): TextRequest {\n const messages = messageFormatter.toCoreMessages(context);\n messages.push({ role: \"user\", content: userMessage });\n return {\n messages,\n systemPrompt: this.resolveSystemPrompt(),\n model: this.config.model,\n tier: this.config.tier,\n temperature: this.config.temperature,\n maxTokens: this.config.maxTokens,\n ...(signal !== undefined ? { signal } : {}),\n };\n }\n\n private resolveSystemPrompt(): string | undefined {\n const prompt = this.promptStrategy.resolve(this.config);\n return prompt && prompt.length > 0 ? prompt : undefined;\n }\n\n private async run(request: TextRequest): Promise<GenerationResult> {\n if (this.engine instanceof ProviderFactory) {\n return this.engine.chat(request);\n }\n return this.engine.generate(request);\n }\n\n private async runStream(\n request: TextRequest,\n callbacks: Pick<StreamCallbacks, \"onChunk\">,\n ): Promise<GenerationResult> {\n if (this.engine instanceof ProviderFactory) {\n return this.engine.chatStream(request, callbacks);\n }\n return this.engine.stream(request, callbacks);\n }\n\n private requireStorage(): IChatStorage {\n if (!this.storage) {\n throw new AIError(\n AIErrorType.MISSING_CONFIG,\n \"ChatService.getConversation requires setStorage() to be called first.\",\n );\n }\n return this.storage;\n }\n}\n\nexport function extractTokenUsage(message: ChatMessage): ChatTokenUsage | null {\n const meta = message.metadata;\n if (!meta) return null;\n const usage = meta[\"usage\"];\n if (!usage || typeof usage !== \"object\") return null;\n const u = usage as Record<string, unknown>;\n const inputTokens = readNumber(u, [\"input_tokens\", \"prompt_tokens\"]);\n const outputTokens = readNumber(u, [\"output_tokens\", \"completion_tokens\"]);\n const totalTokens = readNumber(u, [\"total_tokens\"]);\n if (inputTokens === null || outputTokens === null || totalTokens === null) {\n return null;\n }\n return {\n promptTokens: inputTokens,\n completionTokens: outputTokens,\n totalTokens,\n };\n}\n\nfunction readNumber(\n source: Record<string, unknown>,\n keys: ReadonlyArray<string>,\n): number | null {\n for (const key of keys) {\n const value = source[key];\n if (typeof value === \"number\") return value;\n }\n return null;\n}\n"]}
|
package/dist/chat/index.d.cts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { h as IMessageFormatter, f as ChatMessage } from '../chat.service-
|
|
2
|
-
export { C as ChatConfig, a as ChatConversation, b as ChatMessageSender, c as ChatMessageType, d as ChatService, e as ChatTokenUsage, D as DEFAULT_PROMPT_STRATEGY, I as IChatService, g as IChatStorage, S as SendMessageInput, i as SendMessageResult, j as SystemPromptStrategy, U as UseChatOptions, k as UseChatReturn, l as extractTokenUsage } from '../chat.service-
|
|
1
|
+
import { h as IMessageFormatter, f as ChatMessage } from '../chat.service-CL1qtYxe.cjs';
|
|
2
|
+
export { C as ChatConfig, a as ChatConversation, b as ChatMessageSender, c as ChatMessageType, d as ChatService, e as ChatTokenUsage, D as DEFAULT_PROMPT_STRATEGY, I as IChatService, g as IChatStorage, S as SendMessageInput, i as SendMessageResult, j as SystemPromptStrategy, U as UseChatOptions, k as UseChatReturn, l as extractTokenUsage } from '../chat.service-CL1qtYxe.cjs';
|
|
3
3
|
import { C as ChatMessage$1 } from '../index-fXjxTR5W.cjs';
|
|
4
|
-
import '../provider.factory-
|
|
5
|
-
import '../ProviderConfig-
|
|
4
|
+
import '../provider.factory-BxsfK4WW.cjs';
|
|
5
|
+
import '../ProviderConfig-DIFa9nmG.cjs';
|
|
6
6
|
|
|
7
7
|
declare class ChatIdGenerator {
|
|
8
8
|
private counter;
|
package/dist/chat/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { h as IMessageFormatter, f as ChatMessage } from '../chat.service-
|
|
2
|
-
export { C as ChatConfig, a as ChatConversation, b as ChatMessageSender, c as ChatMessageType, d as ChatService, e as ChatTokenUsage, D as DEFAULT_PROMPT_STRATEGY, I as IChatService, g as IChatStorage, S as SendMessageInput, i as SendMessageResult, j as SystemPromptStrategy, U as UseChatOptions, k as UseChatReturn, l as extractTokenUsage } from '../chat.service-
|
|
1
|
+
import { h as IMessageFormatter, f as ChatMessage } from '../chat.service-q05GnhEm.js';
|
|
2
|
+
export { C as ChatConfig, a as ChatConversation, b as ChatMessageSender, c as ChatMessageType, d as ChatService, e as ChatTokenUsage, D as DEFAULT_PROMPT_STRATEGY, I as IChatService, g as IChatStorage, S as SendMessageInput, i as SendMessageResult, j as SystemPromptStrategy, U as UseChatOptions, k as UseChatReturn, l as extractTokenUsage } from '../chat.service-q05GnhEm.js';
|
|
3
3
|
import { C as ChatMessage$1 } from '../index-fXjxTR5W.js';
|
|
4
|
-
import '../provider.factory-
|
|
5
|
-
import '../ProviderConfig-
|
|
4
|
+
import '../provider.factory-DfDfk0dK.js';
|
|
5
|
+
import '../ProviderConfig-DIFa9nmG.js';
|
|
6
6
|
|
|
7
7
|
declare class ChatIdGenerator {
|
|
8
8
|
private counter;
|