@mgvdev/nestjs-ai 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +655 -0
- package/dist/ai-module-options.interface-B5X4AFLC.d.cts +192 -0
- package/dist/ai-module-options.interface-Ca6y_MY2.d.ts +192 -0
- package/dist/conversation-store.interface-CtQY-qcc.d.cts +30 -0
- package/dist/conversation-store.interface-CtQY-qcc.d.ts +30 -0
- package/dist/index.cjs +3209 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +1441 -0
- package/dist/index.d.ts +1441 -0
- package/dist/index.js +3163 -0
- package/dist/index.js.map +1 -0
- package/dist/stream-to-socket-fJphU0WN.d.cts +47 -0
- package/dist/stream-to-socket-fJphU0WN.d.ts +47 -0
- package/dist/testing.cjs +2395 -0
- package/dist/testing.cjs.map +1 -0
- package/dist/testing.d.cts +46 -0
- package/dist/testing.d.ts +46 -0
- package/dist/testing.js +2391 -0
- package/dist/testing.js.map +1 -0
- package/dist/typeorm.cjs +115 -0
- package/dist/typeorm.cjs.map +1 -0
- package/dist/typeorm.d.cts +44 -0
- package/dist/typeorm.d.ts +44 -0
- package/dist/typeorm.js +113 -0
- package/dist/typeorm.js.map +1 -0
- package/dist/websocket.cjs +154 -0
- package/dist/websocket.cjs.map +1 -0
- package/dist/websocket.d.cts +25 -0
- package/dist/websocket.d.ts +25 -0
- package/dist/websocket.js +152 -0
- package/dist/websocket.js.map +1 -0
- package/documentation/README.md +44 -0
- package/documentation/agents-and-tools.md +102 -0
- package/documentation/api-reference.md +117 -0
- package/documentation/configuration.md +87 -0
- package/documentation/content-safety.md +51 -0
- package/documentation/embeddings-and-rag.md +105 -0
- package/documentation/evals-and-testing.md +56 -0
- package/documentation/getting-started.md +96 -0
- package/documentation/guardrails-events-telemetry.md +72 -0
- package/documentation/jobs-and-realtime.md +69 -0
- package/documentation/memory.md +101 -0
- package/documentation/multimodal.md +49 -0
- package/documentation/orchestration-and-mcp.md +68 -0
- package/documentation/prompts.md +51 -0
- package/documentation/reliability.md +90 -0
- package/documentation/structured-output-and-streaming.md +81 -0
- package/package.json +146 -0
- package/skill/nestjs-ai/SKILL.md +154 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,3209 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
require('reflect-metadata');
|
|
4
|
+
var common = require('@nestjs/common');
|
|
5
|
+
var core = require('@nestjs/core');
|
|
6
|
+
var ai = require('ai');
|
|
7
|
+
var zod = require('zod');
|
|
8
|
+
var rxjs = require('rxjs');
|
|
9
|
+
|
|
10
|
+
var __defProp = Object.defineProperty;
|
|
11
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
12
|
+
|
|
13
|
+
// src/ai.constants.ts
|
|
14
|
+
var AI_MODULE_OPTIONS = /* @__PURE__ */ Symbol("AI_MODULE_OPTIONS");
|
|
15
|
+
var CONVERSATION_STORE = /* @__PURE__ */ Symbol("CONVERSATION_STORE");
|
|
16
|
+
var VECTOR_STORE = /* @__PURE__ */ Symbol("VECTOR_STORE");
|
|
17
|
+
var AI_CACHE = /* @__PURE__ */ Symbol("AI_CACHE");
|
|
18
|
+
var APPROVAL_GATE = /* @__PURE__ */ Symbol("APPROVAL_GATE");
|
|
19
|
+
var AGENT_QUEUE = /* @__PURE__ */ Symbol("AGENT_QUEUE");
|
|
20
|
+
var RATE_LIMITER = /* @__PURE__ */ Symbol("RATE_LIMITER");
|
|
21
|
+
var RERANKER = /* @__PURE__ */ Symbol("RERANKER");
|
|
22
|
+
var TOOL_METADATA = /* @__PURE__ */ Symbol("nestjs-ai:tool");
|
|
23
|
+
var AGENT_METADATA = /* @__PURE__ */ Symbol("nestjs-ai:agent");
|
|
24
|
+
var GUARDRAIL_METADATA = /* @__PURE__ */ Symbol("nestjs-ai:guardrail");
|
|
25
|
+
var DEFAULT_MAX_STEPS = 5;
|
|
26
|
+
|
|
27
|
+
// src/resilience/fallback-model.ts
|
|
28
|
+
function createFallbackModel(models, options = {}) {
|
|
29
|
+
if (models.length === 0) {
|
|
30
|
+
throw new Error("createFallbackModel requires at least one model.");
|
|
31
|
+
}
|
|
32
|
+
const primary = models[0];
|
|
33
|
+
const shouldRetry = options.shouldRetry ?? (() => true);
|
|
34
|
+
async function attempt(call) {
|
|
35
|
+
let lastError;
|
|
36
|
+
for (let i = 0; i < models.length; i++) {
|
|
37
|
+
try {
|
|
38
|
+
return await call(models[i]);
|
|
39
|
+
} catch (error) {
|
|
40
|
+
lastError = error;
|
|
41
|
+
const isLast = i === models.length - 1;
|
|
42
|
+
if (isLast || !shouldRetry(error)) {
|
|
43
|
+
throw error;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
throw lastError;
|
|
48
|
+
}
|
|
49
|
+
__name(attempt, "attempt");
|
|
50
|
+
return {
|
|
51
|
+
specificationVersion: "v3",
|
|
52
|
+
provider: options.provider ?? `fallback(${primary.provider})`,
|
|
53
|
+
modelId: primary.modelId,
|
|
54
|
+
get supportedUrls() {
|
|
55
|
+
return primary.supportedUrls;
|
|
56
|
+
},
|
|
57
|
+
doGenerate: /* @__PURE__ */ __name((callOptions) => attempt((model) => model.doGenerate(callOptions)), "doGenerate"),
|
|
58
|
+
doStream: /* @__PURE__ */ __name((callOptions) => attempt((model) => model.doStream(callOptions)), "doStream")
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
__name(createFallbackModel, "createFallbackModel");
|
|
62
|
+
|
|
63
|
+
// src/cache/cache-middleware.ts
|
|
64
|
+
function createCacheMiddleware(cache, options = {}) {
|
|
65
|
+
return {
|
|
66
|
+
async wrapGenerate({ doGenerate, params, model }) {
|
|
67
|
+
const key = cacheKey(model.modelId, params);
|
|
68
|
+
const cached = await cache.get(key);
|
|
69
|
+
if (cached !== void 0) {
|
|
70
|
+
return cached;
|
|
71
|
+
}
|
|
72
|
+
const result = await doGenerate();
|
|
73
|
+
await cache.set(key, result, options.ttlMs);
|
|
74
|
+
return result;
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
__name(createCacheMiddleware, "createCacheMiddleware");
|
|
79
|
+
function cacheKey(modelId, params) {
|
|
80
|
+
return `${modelId}:${stableStringify(params)}`;
|
|
81
|
+
}
|
|
82
|
+
__name(cacheKey, "cacheKey");
|
|
83
|
+
function stableStringify(value) {
|
|
84
|
+
return JSON.stringify(value, (_key, val) => {
|
|
85
|
+
if (val && typeof val === "object" && !Array.isArray(val)) {
|
|
86
|
+
return Object.keys(val).sort().reduce((acc, k) => {
|
|
87
|
+
acc[k] = val[k];
|
|
88
|
+
return acc;
|
|
89
|
+
}, {});
|
|
90
|
+
}
|
|
91
|
+
return val;
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
__name(stableStringify, "stableStringify");
|
|
95
|
+
|
|
96
|
+
// src/core/provider-registry.ts
|
|
97
|
+
function _ts_decorate(decorators, target, key, desc) {
|
|
98
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
99
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
100
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
101
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
102
|
+
}
|
|
103
|
+
__name(_ts_decorate, "_ts_decorate");
|
|
104
|
+
function _ts_metadata(k, v) {
|
|
105
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
106
|
+
}
|
|
107
|
+
__name(_ts_metadata, "_ts_metadata");
|
|
108
|
+
function _ts_param(paramIndex, decorator) {
|
|
109
|
+
return function(target, key) {
|
|
110
|
+
decorator(target, key, paramIndex);
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
__name(_ts_param, "_ts_param");
|
|
114
|
+
exports.ProviderRegistry = class ProviderRegistry {
|
|
115
|
+
static {
|
|
116
|
+
__name(this, "ProviderRegistry");
|
|
117
|
+
}
|
|
118
|
+
options;
|
|
119
|
+
cache;
|
|
120
|
+
providers = /* @__PURE__ */ new Map();
|
|
121
|
+
constructor(options, cache) {
|
|
122
|
+
this.options = options;
|
|
123
|
+
this.cache = cache;
|
|
124
|
+
}
|
|
125
|
+
/** Wraps a model with the cache middleware when a cache is configured. */
|
|
126
|
+
applyCache(model) {
|
|
127
|
+
if (!this.cache || typeof model === "string") {
|
|
128
|
+
return model;
|
|
129
|
+
}
|
|
130
|
+
return ai.wrapLanguageModel({
|
|
131
|
+
model,
|
|
132
|
+
middleware: createCacheMiddleware(this.cache, {
|
|
133
|
+
ttlMs: this.options.cacheTtlMs
|
|
134
|
+
})
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
async onModuleInit() {
|
|
138
|
+
const configured = this.options.providers ?? {};
|
|
139
|
+
for (const name of Object.keys(configured)) {
|
|
140
|
+
const config = configured[name];
|
|
141
|
+
if (config) {
|
|
142
|
+
await this.initProvider(name, config);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Resolves a language model. Accepts a `LanguageModel` instance (returned
|
|
148
|
+
* as-is), a `"provider:model"` string, a bare `"model"` string (using the
|
|
149
|
+
* default provider), or `undefined` (using `defaultModel`).
|
|
150
|
+
*/
|
|
151
|
+
getLanguageModel(model) {
|
|
152
|
+
const chain = model ?? this.options.defaultModel;
|
|
153
|
+
if (Array.isArray(chain)) {
|
|
154
|
+
if (chain.length === 0) {
|
|
155
|
+
throw new Error("An empty model array was provided.");
|
|
156
|
+
}
|
|
157
|
+
if (chain.length === 1) {
|
|
158
|
+
return this.getLanguageModel(chain[0]);
|
|
159
|
+
}
|
|
160
|
+
const resolved = chain.map((m) => this.resolveSingle(m));
|
|
161
|
+
return this.applyCache(createFallbackModel(resolved));
|
|
162
|
+
}
|
|
163
|
+
return this.applyCache(this.resolveSingle(chain));
|
|
164
|
+
}
|
|
165
|
+
/** Resolves a single (non-array) model reference without cache wrapping. */
|
|
166
|
+
resolveSingle(model) {
|
|
167
|
+
if (model && typeof model !== "string") {
|
|
168
|
+
return model;
|
|
169
|
+
}
|
|
170
|
+
const { provider, modelId } = this.resolve(model, void 0);
|
|
171
|
+
return provider.languageModel(modelId);
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Resolves an embedding model from a `"provider:model"` string, a bare model
|
|
175
|
+
* string, an `EmbeddingModel` instance, or `undefined` (using
|
|
176
|
+
* `defaultEmbeddingModel`).
|
|
177
|
+
*/
|
|
178
|
+
getEmbeddingModel(model) {
|
|
179
|
+
if (model && typeof model !== "string") {
|
|
180
|
+
return model;
|
|
181
|
+
}
|
|
182
|
+
const { name, provider, modelId } = this.resolve(model, this.options.defaultEmbeddingModel);
|
|
183
|
+
if (typeof provider.textEmbeddingModel !== "function") {
|
|
184
|
+
throw new Error(`Provider "${name}" does not support embeddings. Configure a provider with embedding support (e.g. openai or google).`);
|
|
185
|
+
}
|
|
186
|
+
return provider.textEmbeddingModel(modelId);
|
|
187
|
+
}
|
|
188
|
+
/** Resolves an image-generation model (default `defaultImageModel`). */
|
|
189
|
+
getImageModel(model) {
|
|
190
|
+
if (model && typeof model !== "string") {
|
|
191
|
+
return model;
|
|
192
|
+
}
|
|
193
|
+
return this.resolveMultimodal(model, this.options.defaultImageModel, [
|
|
194
|
+
"imageModel",
|
|
195
|
+
"image"
|
|
196
|
+
], "image generation");
|
|
197
|
+
}
|
|
198
|
+
/** Resolves a reranking model (default `rerankingModel` option). */
|
|
199
|
+
getRerankingModel(model) {
|
|
200
|
+
if (model && typeof model !== "string") {
|
|
201
|
+
return model;
|
|
202
|
+
}
|
|
203
|
+
return this.resolveMultimodal(model, this.options.rerankingModel, [
|
|
204
|
+
"rerankingModel",
|
|
205
|
+
"reranking"
|
|
206
|
+
], "reranking");
|
|
207
|
+
}
|
|
208
|
+
/** Resolves a speech (text-to-speech) model (default `defaultSpeechModel`). */
|
|
209
|
+
getSpeechModel(model) {
|
|
210
|
+
if (model && typeof model !== "string") {
|
|
211
|
+
return model;
|
|
212
|
+
}
|
|
213
|
+
return this.resolveMultimodal(model, this.options.defaultSpeechModel, [
|
|
214
|
+
"speechModel",
|
|
215
|
+
"speech"
|
|
216
|
+
], "speech");
|
|
217
|
+
}
|
|
218
|
+
/** Resolves a transcription (speech-to-text) model. */
|
|
219
|
+
getTranscriptionModel(model) {
|
|
220
|
+
if (model && typeof model !== "string") {
|
|
221
|
+
return model;
|
|
222
|
+
}
|
|
223
|
+
return this.resolveMultimodal(model, this.options.defaultTranscriptionModel, [
|
|
224
|
+
"transcriptionModel",
|
|
225
|
+
"transcription"
|
|
226
|
+
], "transcription");
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Shared resolution for multimodal models: resolves the provider, then calls
|
|
230
|
+
* the first available factory method (standard name, then shorthand).
|
|
231
|
+
*/
|
|
232
|
+
resolveMultimodal(model, fallback, methods, capability) {
|
|
233
|
+
const { name, provider, modelId } = this.resolve(model, fallback);
|
|
234
|
+
for (const method of methods) {
|
|
235
|
+
const fn = provider[method];
|
|
236
|
+
if (typeof fn === "function") {
|
|
237
|
+
return fn.call(provider, modelId);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
throw new Error(`Provider "${name}" does not support ${capability}. Configure a provider that does (e.g. openai).`);
|
|
241
|
+
}
|
|
242
|
+
resolve(model, fallback) {
|
|
243
|
+
const raw = model ?? fallback;
|
|
244
|
+
if (!raw) {
|
|
245
|
+
throw new Error("No model specified and no default model configured. Pass a model id or set `defaultModel` in AiModule options.");
|
|
246
|
+
}
|
|
247
|
+
const name = this.parseProviderName(raw);
|
|
248
|
+
const modelId = this.parseModelId(raw);
|
|
249
|
+
const provider = this.providers.get(name);
|
|
250
|
+
if (!provider) {
|
|
251
|
+
throw new Error(`Provider "${name}" is not configured. Add it to AiModule \`providers\` options and install \`@ai-sdk/${name}\`.`);
|
|
252
|
+
}
|
|
253
|
+
return {
|
|
254
|
+
name,
|
|
255
|
+
provider,
|
|
256
|
+
modelId
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
parseProviderName(raw) {
|
|
260
|
+
const sep = raw.indexOf(":");
|
|
261
|
+
if (sep !== -1) {
|
|
262
|
+
return raw.slice(0, sep);
|
|
263
|
+
}
|
|
264
|
+
if (this.providers.size === 1) {
|
|
265
|
+
return this.providers.keys().next().value;
|
|
266
|
+
}
|
|
267
|
+
const def = this.options.defaultModel;
|
|
268
|
+
if (def && def.includes(":")) {
|
|
269
|
+
return def.slice(0, def.indexOf(":"));
|
|
270
|
+
}
|
|
271
|
+
throw new Error(`Cannot infer provider for model "${raw}". Prefix it as "provider:model" (e.g. "openai:${raw}").`);
|
|
272
|
+
}
|
|
273
|
+
parseModelId(raw) {
|
|
274
|
+
const sep = raw.indexOf(":");
|
|
275
|
+
return sep !== -1 ? raw.slice(sep + 1) : raw;
|
|
276
|
+
}
|
|
277
|
+
async initProvider(name, config) {
|
|
278
|
+
const settings = {
|
|
279
|
+
apiKey: config.apiKey,
|
|
280
|
+
baseURL: config.baseURL,
|
|
281
|
+
headers: config.headers
|
|
282
|
+
};
|
|
283
|
+
try {
|
|
284
|
+
switch (name) {
|
|
285
|
+
case "openai": {
|
|
286
|
+
const { createOpenAI } = await import('@ai-sdk/openai');
|
|
287
|
+
this.providers.set(name, createOpenAI(settings));
|
|
288
|
+
break;
|
|
289
|
+
}
|
|
290
|
+
case "anthropic": {
|
|
291
|
+
const { createAnthropic } = await import('@ai-sdk/anthropic');
|
|
292
|
+
this.providers.set(name, createAnthropic(settings));
|
|
293
|
+
break;
|
|
294
|
+
}
|
|
295
|
+
case "google": {
|
|
296
|
+
const { createGoogleGenerativeAI } = await import('@ai-sdk/google');
|
|
297
|
+
this.providers.set(name, createGoogleGenerativeAI(settings));
|
|
298
|
+
break;
|
|
299
|
+
}
|
|
300
|
+
default: {
|
|
301
|
+
throw new Error(`Unknown provider "${name}".`);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
} catch (error) {
|
|
305
|
+
if (error instanceof Error && /Cannot find|find module/i.test(error.message)) {
|
|
306
|
+
throw new Error(`Provider "${name}" is configured but the package "@ai-sdk/${name}" is not installed. Run \`npm install @ai-sdk/${name}\`.`);
|
|
307
|
+
}
|
|
308
|
+
throw error;
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
};
|
|
312
|
+
exports.ProviderRegistry = _ts_decorate([
|
|
313
|
+
common.Injectable(),
|
|
314
|
+
_ts_param(0, common.Inject(AI_MODULE_OPTIONS)),
|
|
315
|
+
_ts_param(1, common.Optional()),
|
|
316
|
+
_ts_param(1, common.Inject(AI_CACHE)),
|
|
317
|
+
_ts_metadata("design:type", Function),
|
|
318
|
+
_ts_metadata("design:paramtypes", [
|
|
319
|
+
typeof AiModuleOptions === "undefined" ? Object : AiModuleOptions,
|
|
320
|
+
typeof AiCache === "undefined" ? Object : AiCache
|
|
321
|
+
])
|
|
322
|
+
], exports.ProviderRegistry);
|
|
323
|
+
function _ts_decorate2(decorators, target, key, desc) {
|
|
324
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
325
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
326
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
327
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
328
|
+
}
|
|
329
|
+
__name(_ts_decorate2, "_ts_decorate");
|
|
330
|
+
function _ts_metadata2(k, v) {
|
|
331
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
332
|
+
}
|
|
333
|
+
__name(_ts_metadata2, "_ts_metadata");
|
|
334
|
+
function _ts_param2(paramIndex, decorator) {
|
|
335
|
+
return function(target, key) {
|
|
336
|
+
decorator(target, key, paramIndex);
|
|
337
|
+
};
|
|
338
|
+
}
|
|
339
|
+
__name(_ts_param2, "_ts_param");
|
|
340
|
+
var EVENT_EMITTER = /* @__PURE__ */ Symbol("AI_EVENT_EMITTER");
|
|
341
|
+
exports.AiEventEmitter = class AiEventEmitter {
|
|
342
|
+
static {
|
|
343
|
+
__name(this, "AiEventEmitter");
|
|
344
|
+
}
|
|
345
|
+
emitter;
|
|
346
|
+
constructor(emitter) {
|
|
347
|
+
this.emitter = emitter;
|
|
348
|
+
}
|
|
349
|
+
emit(event, payload) {
|
|
350
|
+
this.emitter?.emit(event, payload);
|
|
351
|
+
}
|
|
352
|
+
/** Whether an underlying emitter is wired up. */
|
|
353
|
+
get enabled() {
|
|
354
|
+
return this.emitter != null;
|
|
355
|
+
}
|
|
356
|
+
};
|
|
357
|
+
exports.AiEventEmitter = _ts_decorate2([
|
|
358
|
+
common.Injectable(),
|
|
359
|
+
_ts_param2(0, common.Optional()),
|
|
360
|
+
_ts_param2(0, common.Inject(EVENT_EMITTER)),
|
|
361
|
+
_ts_metadata2("design:type", Function),
|
|
362
|
+
_ts_metadata2("design:paramtypes", [
|
|
363
|
+
Object
|
|
364
|
+
])
|
|
365
|
+
], exports.AiEventEmitter);
|
|
366
|
+
|
|
367
|
+
// src/observability/ai-events.ts
|
|
368
|
+
var AI_EVENTS = {
|
|
369
|
+
agentRunStart: "ai.agent.run.start",
|
|
370
|
+
agentRunFinish: "ai.agent.run.finish",
|
|
371
|
+
agentRunError: "ai.agent.run.error",
|
|
372
|
+
toolCall: "ai.tool.call",
|
|
373
|
+
toolResult: "ai.tool.result",
|
|
374
|
+
streamFinish: "ai.stream.finish",
|
|
375
|
+
usage: "ai.usage"
|
|
376
|
+
};
|
|
377
|
+
function _ts_decorate3(decorators, target, key, desc) {
|
|
378
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
379
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
380
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
381
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
382
|
+
}
|
|
383
|
+
__name(_ts_decorate3, "_ts_decorate");
|
|
384
|
+
function _ts_metadata3(k, v) {
|
|
385
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
386
|
+
}
|
|
387
|
+
__name(_ts_metadata3, "_ts_metadata");
|
|
388
|
+
exports.GuardrailRegistry = class GuardrailRegistry {
|
|
389
|
+
static {
|
|
390
|
+
__name(this, "GuardrailRegistry");
|
|
391
|
+
}
|
|
392
|
+
discovery;
|
|
393
|
+
guardrails = [];
|
|
394
|
+
constructor(discovery) {
|
|
395
|
+
this.discovery = discovery;
|
|
396
|
+
}
|
|
397
|
+
onModuleInit() {
|
|
398
|
+
for (const wrapper of this.discovery.getProviders()) {
|
|
399
|
+
const instance = wrapper.instance;
|
|
400
|
+
const ctor = instance?.constructor;
|
|
401
|
+
if (instance && ctor && Reflect.getMetadata(GUARDRAIL_METADATA, ctor) === true) {
|
|
402
|
+
this.guardrails.push(instance);
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
get count() {
|
|
407
|
+
return this.guardrails.length;
|
|
408
|
+
}
|
|
409
|
+
async runBeforeRun(ctx) {
|
|
410
|
+
for (const guardrail of this.guardrails) {
|
|
411
|
+
await guardrail.beforeRun?.(ctx);
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
async runAfterRun(ctx, result) {
|
|
415
|
+
for (const guardrail of this.guardrails) {
|
|
416
|
+
await guardrail.afterRun?.(ctx, result);
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
async runOnToolCall(tool4, args) {
|
|
420
|
+
for (const guardrail of this.guardrails) {
|
|
421
|
+
await guardrail.onToolCall?.(tool4, args);
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
};
|
|
425
|
+
exports.GuardrailRegistry = _ts_decorate3([
|
|
426
|
+
common.Injectable(),
|
|
427
|
+
_ts_metadata3("design:type", Function),
|
|
428
|
+
_ts_metadata3("design:paramtypes", [
|
|
429
|
+
typeof core.DiscoveryService === "undefined" ? Object : core.DiscoveryService
|
|
430
|
+
])
|
|
431
|
+
], exports.GuardrailRegistry);
|
|
432
|
+
function _ts_decorate4(decorators, target, key, desc) {
|
|
433
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
434
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
435
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
436
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
437
|
+
}
|
|
438
|
+
__name(_ts_decorate4, "_ts_decorate");
|
|
439
|
+
function _ts_metadata4(k, v) {
|
|
440
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
441
|
+
}
|
|
442
|
+
__name(_ts_metadata4, "_ts_metadata");
|
|
443
|
+
exports.AgentRegistry = class AgentRegistry {
|
|
444
|
+
static {
|
|
445
|
+
__name(this, "AgentRegistry");
|
|
446
|
+
}
|
|
447
|
+
discovery;
|
|
448
|
+
agents = /* @__PURE__ */ new Map();
|
|
449
|
+
constructor(discovery) {
|
|
450
|
+
this.discovery = discovery;
|
|
451
|
+
}
|
|
452
|
+
onModuleInit() {
|
|
453
|
+
for (const wrapper of this.discovery.getProviders()) {
|
|
454
|
+
const instance = wrapper.instance;
|
|
455
|
+
const ctor = instance?.constructor;
|
|
456
|
+
if (instance && ctor && Reflect.getMetadata(AGENT_METADATA, ctor)) {
|
|
457
|
+
this.agents.set(ctor.name, {
|
|
458
|
+
name: ctor.name,
|
|
459
|
+
instance,
|
|
460
|
+
target: ctor
|
|
461
|
+
});
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
/** Returns an agent instance by class name. */
|
|
466
|
+
get(name) {
|
|
467
|
+
return this.agents.get(name)?.instance;
|
|
468
|
+
}
|
|
469
|
+
/** Returns an agent instance by its class. */
|
|
470
|
+
getByClass(target) {
|
|
471
|
+
return this.agents.get(target.name)?.instance;
|
|
472
|
+
}
|
|
473
|
+
/** All discovered agents. */
|
|
474
|
+
all() {
|
|
475
|
+
return [
|
|
476
|
+
...this.agents.values()
|
|
477
|
+
];
|
|
478
|
+
}
|
|
479
|
+
};
|
|
480
|
+
exports.AgentRegistry = _ts_decorate4([
|
|
481
|
+
common.Injectable(),
|
|
482
|
+
_ts_metadata4("design:type", Function),
|
|
483
|
+
_ts_metadata4("design:paramtypes", [
|
|
484
|
+
typeof core.DiscoveryService === "undefined" ? Object : core.DiscoveryService
|
|
485
|
+
])
|
|
486
|
+
], exports.AgentRegistry);
|
|
487
|
+
function createAgentTool(agent, options = {}) {
|
|
488
|
+
const schema = options.inputSchema ?? zod.z.object({
|
|
489
|
+
input: zod.z.string().describe("The task or question for the agent")
|
|
490
|
+
});
|
|
491
|
+
return ai.tool({
|
|
492
|
+
description: options.description ?? `Delegate the task to the ${options.name ?? "sub"} agent.`,
|
|
493
|
+
inputSchema: schema,
|
|
494
|
+
execute: /* @__PURE__ */ __name(async (args) => {
|
|
495
|
+
const input = typeof args === "string" ? args : args?.input ?? JSON.stringify(args);
|
|
496
|
+
const result = await agent.run(input);
|
|
497
|
+
return result.text;
|
|
498
|
+
}, "execute")
|
|
499
|
+
});
|
|
500
|
+
}
|
|
501
|
+
__name(createAgentTool, "createAgentTool");
|
|
502
|
+
|
|
503
|
+
// src/approval/approval-gate.interface.ts
|
|
504
|
+
var ToolApprovalDeniedError = class extends Error {
|
|
505
|
+
static {
|
|
506
|
+
__name(this, "ToolApprovalDeniedError");
|
|
507
|
+
}
|
|
508
|
+
tool;
|
|
509
|
+
constructor(tool4) {
|
|
510
|
+
super(`Tool "${tool4}" was denied by the approval gate.`), this.tool = tool4;
|
|
511
|
+
this.name = "ToolApprovalDeniedError";
|
|
512
|
+
}
|
|
513
|
+
};
|
|
514
|
+
|
|
515
|
+
// src/tools/tool.registry.ts
|
|
516
|
+
function _ts_decorate5(decorators, target, key, desc) {
|
|
517
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
518
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
519
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
520
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
521
|
+
}
|
|
522
|
+
__name(_ts_decorate5, "_ts_decorate");
|
|
523
|
+
function _ts_metadata5(k, v) {
|
|
524
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
525
|
+
}
|
|
526
|
+
__name(_ts_metadata5, "_ts_metadata");
|
|
527
|
+
function _ts_param3(paramIndex, decorator) {
|
|
528
|
+
return function(target, key) {
|
|
529
|
+
decorator(target, key, paramIndex);
|
|
530
|
+
};
|
|
531
|
+
}
|
|
532
|
+
__name(_ts_param3, "_ts_param");
|
|
533
|
+
exports.ToolRegistry = class ToolRegistry {
|
|
534
|
+
static {
|
|
535
|
+
__name(this, "ToolRegistry");
|
|
536
|
+
}
|
|
537
|
+
discovery;
|
|
538
|
+
scanner;
|
|
539
|
+
reflector;
|
|
540
|
+
events;
|
|
541
|
+
guardrails;
|
|
542
|
+
approvalGate;
|
|
543
|
+
agentRegistry;
|
|
544
|
+
tools = /* @__PURE__ */ new Map();
|
|
545
|
+
constructor(discovery, scanner, reflector, events, guardrails, approvalGate, agentRegistry) {
|
|
546
|
+
this.discovery = discovery;
|
|
547
|
+
this.scanner = scanner;
|
|
548
|
+
this.reflector = reflector;
|
|
549
|
+
this.events = events;
|
|
550
|
+
this.guardrails = guardrails;
|
|
551
|
+
this.approvalGate = approvalGate;
|
|
552
|
+
this.agentRegistry = agentRegistry;
|
|
553
|
+
}
|
|
554
|
+
onModuleInit() {
|
|
555
|
+
for (const wrapper of this.discovery.getProviders()) {
|
|
556
|
+
const instance = wrapper.instance;
|
|
557
|
+
if (!instance || typeof instance !== "object") {
|
|
558
|
+
continue;
|
|
559
|
+
}
|
|
560
|
+
const prototype = Object.getPrototypeOf(instance);
|
|
561
|
+
if (!prototype) {
|
|
562
|
+
continue;
|
|
563
|
+
}
|
|
564
|
+
for (const methodName of this.scanner.getAllMethodNames(prototype)) {
|
|
565
|
+
const methodRef = instance[methodName];
|
|
566
|
+
const metadata = this.reflector.get(TOOL_METADATA, methodRef);
|
|
567
|
+
if (!metadata) {
|
|
568
|
+
continue;
|
|
569
|
+
}
|
|
570
|
+
this.register(instance, methodName, metadata);
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
register(instance, methodName, metadata) {
|
|
575
|
+
const name = metadata.name ?? methodName;
|
|
576
|
+
if (this.tools.has(name)) {
|
|
577
|
+
throw new Error(`Duplicate AI tool name "${name}". Tool names must be unique across all providers (declared on ${instance.constructor?.name}).`);
|
|
578
|
+
}
|
|
579
|
+
const built = ai.tool({
|
|
580
|
+
description: metadata.description,
|
|
581
|
+
inputSchema: metadata.schema,
|
|
582
|
+
execute: /* @__PURE__ */ __name(async (args, opts) => {
|
|
583
|
+
if (metadata.requiresApproval && this.approvalGate) {
|
|
584
|
+
const approved = await this.approvalGate.requestApproval({
|
|
585
|
+
tool: name,
|
|
586
|
+
args
|
|
587
|
+
});
|
|
588
|
+
if (!approved) {
|
|
589
|
+
throw new ToolApprovalDeniedError(name);
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
await this.guardrails?.runOnToolCall(name, args);
|
|
593
|
+
this.events?.emit(AI_EVENTS.toolCall, {
|
|
594
|
+
tool: name,
|
|
595
|
+
args
|
|
596
|
+
});
|
|
597
|
+
const result = await instance[methodName](args, opts);
|
|
598
|
+
this.events?.emit(AI_EVENTS.toolResult, {
|
|
599
|
+
tool: name,
|
|
600
|
+
args,
|
|
601
|
+
result
|
|
602
|
+
});
|
|
603
|
+
return result;
|
|
604
|
+
}, "execute")
|
|
605
|
+
});
|
|
606
|
+
this.tools.set(name, {
|
|
607
|
+
name,
|
|
608
|
+
tool: built,
|
|
609
|
+
target: instance.constructor
|
|
610
|
+
});
|
|
611
|
+
}
|
|
612
|
+
/** Returns the tool registered under `name`, if any. */
|
|
613
|
+
getByName(name) {
|
|
614
|
+
return this.tools.get(name);
|
|
615
|
+
}
|
|
616
|
+
/** Returns every tool declared by the given provider class. */
|
|
617
|
+
getForClass(target) {
|
|
618
|
+
return [
|
|
619
|
+
...this.tools.values()
|
|
620
|
+
].filter((entry) => entry.target === target);
|
|
621
|
+
}
|
|
622
|
+
/** Returns all discovered tools. */
|
|
623
|
+
getAll() {
|
|
624
|
+
return [
|
|
625
|
+
...this.tools.values()
|
|
626
|
+
];
|
|
627
|
+
}
|
|
628
|
+
/**
|
|
629
|
+
* Builds the `ToolSet` passed to `generateText`/`streamText` from a list of
|
|
630
|
+
* tool references (provider classes and/or tool names). Passing no refs
|
|
631
|
+
* returns every discovered tool.
|
|
632
|
+
*/
|
|
633
|
+
buildToolSet(refs) {
|
|
634
|
+
const entries = refs && refs.length > 0 ? refs.flatMap((ref) => this.resolveRef(ref)) : this.getAll();
|
|
635
|
+
const set = {};
|
|
636
|
+
for (const entry of entries) {
|
|
637
|
+
set[entry.name] = entry.tool;
|
|
638
|
+
}
|
|
639
|
+
return set;
|
|
640
|
+
}
|
|
641
|
+
resolveRef(ref) {
|
|
642
|
+
if (typeof ref === "string") {
|
|
643
|
+
const entry = this.getByName(ref);
|
|
644
|
+
if (!entry) {
|
|
645
|
+
throw new Error(`Unknown AI tool "${ref}".`);
|
|
646
|
+
}
|
|
647
|
+
return [
|
|
648
|
+
entry
|
|
649
|
+
];
|
|
650
|
+
}
|
|
651
|
+
const entries = this.getForClass(ref);
|
|
652
|
+
if (entries.length > 0) {
|
|
653
|
+
return entries;
|
|
654
|
+
}
|
|
655
|
+
const agentEntry = this.resolveAgentRef(ref);
|
|
656
|
+
if (agentEntry) {
|
|
657
|
+
return [
|
|
658
|
+
agentEntry
|
|
659
|
+
];
|
|
660
|
+
}
|
|
661
|
+
throw new Error(`Class "${ref.name}" declares no @Tool methods and is not a registered @Agent, or was not registered as a provider so it could be discovered.`);
|
|
662
|
+
}
|
|
663
|
+
resolveAgentRef(ref) {
|
|
664
|
+
if (!this.agentRegistry || !Reflect.getMetadata(AGENT_METADATA, ref)) {
|
|
665
|
+
return void 0;
|
|
666
|
+
}
|
|
667
|
+
const instance = this.agentRegistry.getByClass(ref);
|
|
668
|
+
if (!instance) {
|
|
669
|
+
return void 0;
|
|
670
|
+
}
|
|
671
|
+
return {
|
|
672
|
+
name: ref.name,
|
|
673
|
+
tool: createAgentTool(instance, {
|
|
674
|
+
name: ref.name
|
|
675
|
+
}),
|
|
676
|
+
target: ref
|
|
677
|
+
};
|
|
678
|
+
}
|
|
679
|
+
};
|
|
680
|
+
exports.ToolRegistry = _ts_decorate5([
|
|
681
|
+
common.Injectable(),
|
|
682
|
+
_ts_param3(3, common.Optional()),
|
|
683
|
+
_ts_param3(4, common.Optional()),
|
|
684
|
+
_ts_param3(5, common.Optional()),
|
|
685
|
+
_ts_param3(5, common.Inject(APPROVAL_GATE)),
|
|
686
|
+
_ts_param3(6, common.Optional()),
|
|
687
|
+
_ts_metadata5("design:type", Function),
|
|
688
|
+
_ts_metadata5("design:paramtypes", [
|
|
689
|
+
typeof core.DiscoveryService === "undefined" ? Object : core.DiscoveryService,
|
|
690
|
+
typeof core.MetadataScanner === "undefined" ? Object : core.MetadataScanner,
|
|
691
|
+
typeof core.Reflector === "undefined" ? Object : core.Reflector,
|
|
692
|
+
typeof exports.AiEventEmitter === "undefined" ? Object : exports.AiEventEmitter,
|
|
693
|
+
typeof exports.GuardrailRegistry === "undefined" ? Object : exports.GuardrailRegistry,
|
|
694
|
+
typeof ApprovalGate === "undefined" ? Object : ApprovalGate,
|
|
695
|
+
typeof exports.AgentRegistry === "undefined" ? Object : exports.AgentRegistry
|
|
696
|
+
])
|
|
697
|
+
], exports.ToolRegistry);
|
|
698
|
+
|
|
699
|
+
// src/core/ai.service.ts
|
|
700
|
+
function _ts_decorate6(decorators, target, key, desc) {
|
|
701
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
702
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
703
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
704
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
705
|
+
}
|
|
706
|
+
__name(_ts_decorate6, "_ts_decorate");
|
|
707
|
+
function _ts_metadata6(k, v) {
|
|
708
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
709
|
+
}
|
|
710
|
+
__name(_ts_metadata6, "_ts_metadata");
|
|
711
|
+
exports.AiService = class AiService {
|
|
712
|
+
static {
|
|
713
|
+
__name(this, "AiService");
|
|
714
|
+
}
|
|
715
|
+
providers;
|
|
716
|
+
toolRegistry;
|
|
717
|
+
constructor(providers, toolRegistry) {
|
|
718
|
+
this.providers = providers;
|
|
719
|
+
this.toolRegistry = toolRegistry;
|
|
720
|
+
}
|
|
721
|
+
generateText(params) {
|
|
722
|
+
return ai.generateText(this.resolve(params));
|
|
723
|
+
}
|
|
724
|
+
streamText(params) {
|
|
725
|
+
return ai.streamText(this.resolve(params));
|
|
726
|
+
}
|
|
727
|
+
generateObject(params) {
|
|
728
|
+
return ai.generateObject(this.resolve(params));
|
|
729
|
+
}
|
|
730
|
+
streamObject(params) {
|
|
731
|
+
return ai.streamObject(this.resolve(params));
|
|
732
|
+
}
|
|
733
|
+
resolve(params) {
|
|
734
|
+
const { model, tools, ...rest } = params;
|
|
735
|
+
return {
|
|
736
|
+
...rest,
|
|
737
|
+
model: this.providers.getLanguageModel(model),
|
|
738
|
+
...tools ? {
|
|
739
|
+
tools: this.toolRegistry.buildToolSet(tools)
|
|
740
|
+
} : {}
|
|
741
|
+
};
|
|
742
|
+
}
|
|
743
|
+
};
|
|
744
|
+
exports.AiService = _ts_decorate6([
|
|
745
|
+
common.Injectable(),
|
|
746
|
+
_ts_metadata6("design:type", Function),
|
|
747
|
+
_ts_metadata6("design:paramtypes", [
|
|
748
|
+
typeof exports.ProviderRegistry === "undefined" ? Object : exports.ProviderRegistry,
|
|
749
|
+
typeof exports.ToolRegistry === "undefined" ? Object : exports.ToolRegistry
|
|
750
|
+
])
|
|
751
|
+
], exports.AiService);
|
|
752
|
+
|
|
753
|
+
// src/messages/message.types.ts
|
|
754
|
+
function toMessages(input) {
|
|
755
|
+
if (typeof input === "string") {
|
|
756
|
+
return [
|
|
757
|
+
{
|
|
758
|
+
role: "user",
|
|
759
|
+
content: input
|
|
760
|
+
}
|
|
761
|
+
];
|
|
762
|
+
}
|
|
763
|
+
return input;
|
|
764
|
+
}
|
|
765
|
+
__name(toMessages, "toMessages");
|
|
766
|
+
|
|
767
|
+
// src/prompts/prompt.types.ts
|
|
768
|
+
var PLACEHOLDER = /\{\{\s*([\w.]+)\s*\}\}/g;
|
|
769
|
+
function interpolate(template, vars = {}) {
|
|
770
|
+
return template.replace(PLACEHOLDER, (_match, key) => {
|
|
771
|
+
if (!(key in vars)) {
|
|
772
|
+
throw new Error(`Missing variable "${key}" for prompt interpolation.`);
|
|
773
|
+
}
|
|
774
|
+
const value = vars[key];
|
|
775
|
+
return value == null ? "" : String(value);
|
|
776
|
+
});
|
|
777
|
+
}
|
|
778
|
+
__name(interpolate, "interpolate");
|
|
779
|
+
|
|
780
|
+
// src/prompts/prompt-registry.service.ts
|
|
781
|
+
function _ts_decorate7(decorators, target, key, desc) {
|
|
782
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
783
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
784
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
785
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
786
|
+
}
|
|
787
|
+
__name(_ts_decorate7, "_ts_decorate");
|
|
788
|
+
var DEFAULT_VERSION = "__default__";
|
|
789
|
+
exports.PromptRegistry = class PromptRegistry {
|
|
790
|
+
static {
|
|
791
|
+
__name(this, "PromptRegistry");
|
|
792
|
+
}
|
|
793
|
+
/** name -> (version -> definition) */
|
|
794
|
+
prompts = /* @__PURE__ */ new Map();
|
|
795
|
+
/** name -> most recently registered version key */
|
|
796
|
+
latest = /* @__PURE__ */ new Map();
|
|
797
|
+
/** Registers a prompt. Throws on a duplicate (name, version). */
|
|
798
|
+
register(definition) {
|
|
799
|
+
const versions = this.prompts.get(definition.name) ?? /* @__PURE__ */ new Map();
|
|
800
|
+
const versionKey = definition.version ?? DEFAULT_VERSION;
|
|
801
|
+
if (versions.has(versionKey)) {
|
|
802
|
+
throw new Error(`Prompt "${definition.name}"${definition.version ? ` version "${definition.version}"` : ""} is already registered.`);
|
|
803
|
+
}
|
|
804
|
+
versions.set(versionKey, definition);
|
|
805
|
+
this.prompts.set(definition.name, versions);
|
|
806
|
+
this.latest.set(definition.name, versionKey);
|
|
807
|
+
}
|
|
808
|
+
/** Registers many prompts. */
|
|
809
|
+
registerAll(definitions) {
|
|
810
|
+
for (const definition of definitions) {
|
|
811
|
+
this.register(definition);
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
/** Returns a prompt definition (latest version when `version` omitted). */
|
|
815
|
+
get(name, version) {
|
|
816
|
+
const versions = this.prompts.get(name);
|
|
817
|
+
if (!versions) {
|
|
818
|
+
throw new Error(`Unknown prompt "${name}".`);
|
|
819
|
+
}
|
|
820
|
+
const versionKey = version ?? this.latest.get(name) ?? DEFAULT_VERSION;
|
|
821
|
+
const definition = versions.get(versionKey);
|
|
822
|
+
if (!definition) {
|
|
823
|
+
throw new Error(`Unknown version "${version}" for prompt "${name}".`);
|
|
824
|
+
}
|
|
825
|
+
return definition;
|
|
826
|
+
}
|
|
827
|
+
/** Renders a prompt to a string, interpolating `{{var}}` placeholders. */
|
|
828
|
+
render(name, vars = {}, options = {}) {
|
|
829
|
+
return interpolate(this.get(name, options.version).template, vars);
|
|
830
|
+
}
|
|
831
|
+
/** Whether a prompt (any version) is registered. */
|
|
832
|
+
has(name) {
|
|
833
|
+
return this.prompts.has(name);
|
|
834
|
+
}
|
|
835
|
+
};
|
|
836
|
+
exports.PromptRegistry = _ts_decorate7([
|
|
837
|
+
common.Injectable()
|
|
838
|
+
], exports.PromptRegistry);
|
|
839
|
+
|
|
840
|
+
// src/usage/pricing.ts
|
|
841
|
+
var DEFAULT_PRICING = {
|
|
842
|
+
"gpt-4o": {
|
|
843
|
+
input: 2.5,
|
|
844
|
+
output: 10
|
|
845
|
+
},
|
|
846
|
+
"gpt-4o-mini": {
|
|
847
|
+
input: 0.15,
|
|
848
|
+
output: 0.6
|
|
849
|
+
},
|
|
850
|
+
"gpt-4.1": {
|
|
851
|
+
input: 2,
|
|
852
|
+
output: 8
|
|
853
|
+
},
|
|
854
|
+
"gpt-4.1-mini": {
|
|
855
|
+
input: 0.4,
|
|
856
|
+
output: 1.6
|
|
857
|
+
},
|
|
858
|
+
"o3-mini": {
|
|
859
|
+
input: 1.1,
|
|
860
|
+
output: 4.4
|
|
861
|
+
},
|
|
862
|
+
"text-embedding-3-small": {
|
|
863
|
+
input: 0.02,
|
|
864
|
+
output: 0
|
|
865
|
+
},
|
|
866
|
+
"text-embedding-3-large": {
|
|
867
|
+
input: 0.13,
|
|
868
|
+
output: 0
|
|
869
|
+
},
|
|
870
|
+
"claude-sonnet-4": {
|
|
871
|
+
input: 3,
|
|
872
|
+
output: 15
|
|
873
|
+
},
|
|
874
|
+
"claude-opus-4": {
|
|
875
|
+
input: 15,
|
|
876
|
+
output: 75
|
|
877
|
+
},
|
|
878
|
+
"claude-haiku-4": {
|
|
879
|
+
input: 0.8,
|
|
880
|
+
output: 4
|
|
881
|
+
},
|
|
882
|
+
"gemini-2.5-pro": {
|
|
883
|
+
input: 1.25,
|
|
884
|
+
output: 10
|
|
885
|
+
},
|
|
886
|
+
"gemini-2.5-flash": {
|
|
887
|
+
input: 0.3,
|
|
888
|
+
output: 2.5
|
|
889
|
+
}
|
|
890
|
+
};
|
|
891
|
+
function bareModelId(modelId) {
|
|
892
|
+
const sep = modelId.indexOf(":");
|
|
893
|
+
return sep === -1 ? modelId : modelId.slice(sep + 1);
|
|
894
|
+
}
|
|
895
|
+
__name(bareModelId, "bareModelId");
|
|
896
|
+
function costOf(usage, modelId, pricing = DEFAULT_PRICING) {
|
|
897
|
+
const price = pricing[bareModelId(modelId)] ?? pricing[modelId];
|
|
898
|
+
if (!price) {
|
|
899
|
+
return 0;
|
|
900
|
+
}
|
|
901
|
+
const input = usage.inputTokens ?? 0;
|
|
902
|
+
const output = usage.outputTokens ?? 0;
|
|
903
|
+
return input / 1e6 * price.input + output / 1e6 * price.output;
|
|
904
|
+
}
|
|
905
|
+
__name(costOf, "costOf");
|
|
906
|
+
|
|
907
|
+
// src/usage/usage-tracker.service.ts
|
|
908
|
+
function _ts_decorate8(decorators, target, key, desc) {
|
|
909
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
910
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
911
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
912
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
913
|
+
}
|
|
914
|
+
__name(_ts_decorate8, "_ts_decorate");
|
|
915
|
+
function _ts_metadata7(k, v) {
|
|
916
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
917
|
+
}
|
|
918
|
+
__name(_ts_metadata7, "_ts_metadata");
|
|
919
|
+
function _ts_param4(paramIndex, decorator) {
|
|
920
|
+
return function(target, key) {
|
|
921
|
+
decorator(target, key, paramIndex);
|
|
922
|
+
};
|
|
923
|
+
}
|
|
924
|
+
__name(_ts_param4, "_ts_param");
|
|
925
|
+
var GLOBAL = "__global__";
|
|
926
|
+
function empty() {
|
|
927
|
+
return {
|
|
928
|
+
inputTokens: 0,
|
|
929
|
+
outputTokens: 0,
|
|
930
|
+
cost: 0,
|
|
931
|
+
runs: 0
|
|
932
|
+
};
|
|
933
|
+
}
|
|
934
|
+
__name(empty, "empty");
|
|
935
|
+
exports.UsageTracker = class UsageTracker {
|
|
936
|
+
static {
|
|
937
|
+
__name(this, "UsageTracker");
|
|
938
|
+
}
|
|
939
|
+
options;
|
|
940
|
+
events;
|
|
941
|
+
totalsByScope = /* @__PURE__ */ new Map();
|
|
942
|
+
constructor(options, events) {
|
|
943
|
+
this.options = options;
|
|
944
|
+
this.events = events;
|
|
945
|
+
}
|
|
946
|
+
/** Records a run's usage, returns the single-run record, emits `ai.usage`. */
|
|
947
|
+
record(entry) {
|
|
948
|
+
const usage = entry.usage ?? {};
|
|
949
|
+
const inputTokens = usage.inputTokens ?? 0;
|
|
950
|
+
const outputTokens = usage.outputTokens ?? 0;
|
|
951
|
+
const cost = costOf(usage, entry.model, this.options.pricing);
|
|
952
|
+
for (const scope of [
|
|
953
|
+
GLOBAL,
|
|
954
|
+
entry.conversationId
|
|
955
|
+
].filter(Boolean)) {
|
|
956
|
+
const totals = this.totalsByScope.get(scope) ?? empty();
|
|
957
|
+
totals.inputTokens += inputTokens;
|
|
958
|
+
totals.outputTokens += outputTokens;
|
|
959
|
+
totals.cost += cost;
|
|
960
|
+
totals.runs += 1;
|
|
961
|
+
this.totalsByScope.set(scope, totals);
|
|
962
|
+
}
|
|
963
|
+
const record = {
|
|
964
|
+
conversationId: entry.conversationId,
|
|
965
|
+
agent: entry.agent,
|
|
966
|
+
model: entry.model,
|
|
967
|
+
inputTokens,
|
|
968
|
+
outputTokens,
|
|
969
|
+
cost,
|
|
970
|
+
runs: 1
|
|
971
|
+
};
|
|
972
|
+
this.events?.emit(AI_EVENTS.usage, record);
|
|
973
|
+
return record;
|
|
974
|
+
}
|
|
975
|
+
/** Totals for a conversation, or global totals when no id is given. */
|
|
976
|
+
totals(conversationId) {
|
|
977
|
+
return {
|
|
978
|
+
...this.totalsByScope.get(conversationId ?? GLOBAL) ?? empty()
|
|
979
|
+
};
|
|
980
|
+
}
|
|
981
|
+
/** Clears totals for a conversation (or all when no id). */
|
|
982
|
+
reset(conversationId) {
|
|
983
|
+
if (conversationId) {
|
|
984
|
+
this.totalsByScope.delete(conversationId);
|
|
985
|
+
} else {
|
|
986
|
+
this.totalsByScope.clear();
|
|
987
|
+
}
|
|
988
|
+
}
|
|
989
|
+
};
|
|
990
|
+
exports.UsageTracker = _ts_decorate8([
|
|
991
|
+
common.Injectable(),
|
|
992
|
+
_ts_param4(0, common.Inject(AI_MODULE_OPTIONS)),
|
|
993
|
+
_ts_param4(1, common.Optional()),
|
|
994
|
+
_ts_metadata7("design:type", Function),
|
|
995
|
+
_ts_metadata7("design:paramtypes", [
|
|
996
|
+
typeof AiModuleOptions === "undefined" ? Object : AiModuleOptions,
|
|
997
|
+
typeof exports.AiEventEmitter === "undefined" ? Object : exports.AiEventEmitter
|
|
998
|
+
])
|
|
999
|
+
], exports.UsageTracker);
|
|
1000
|
+
function _ts_decorate9(decorators, target, key, desc) {
|
|
1001
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1002
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
1003
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
1004
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
1005
|
+
}
|
|
1006
|
+
__name(_ts_decorate9, "_ts_decorate");
|
|
1007
|
+
function _ts_metadata8(k, v) {
|
|
1008
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
1009
|
+
}
|
|
1010
|
+
__name(_ts_metadata8, "_ts_metadata");
|
|
1011
|
+
function _ts_param5(paramIndex, decorator) {
|
|
1012
|
+
return function(target, key) {
|
|
1013
|
+
decorator(target, key, paramIndex);
|
|
1014
|
+
};
|
|
1015
|
+
}
|
|
1016
|
+
__name(_ts_param5, "_ts_param");
|
|
1017
|
+
exports.EmbeddingsService = class EmbeddingsService {
|
|
1018
|
+
static {
|
|
1019
|
+
__name(this, "EmbeddingsService");
|
|
1020
|
+
}
|
|
1021
|
+
providers;
|
|
1022
|
+
cache;
|
|
1023
|
+
constructor(providers, cache) {
|
|
1024
|
+
this.providers = providers;
|
|
1025
|
+
this.cache = cache;
|
|
1026
|
+
}
|
|
1027
|
+
/** Embeds a single value (cached when a cache is configured). */
|
|
1028
|
+
async embed(value, options = {}) {
|
|
1029
|
+
const model = this.providers.getEmbeddingModel(options.model);
|
|
1030
|
+
const key = `emb:${model.modelId ?? ""}:${value}`;
|
|
1031
|
+
if (this.cache) {
|
|
1032
|
+
const hit = await this.cache.get(key);
|
|
1033
|
+
if (hit !== void 0) {
|
|
1034
|
+
return hit;
|
|
1035
|
+
}
|
|
1036
|
+
}
|
|
1037
|
+
const result = await ai.embed({
|
|
1038
|
+
model,
|
|
1039
|
+
value,
|
|
1040
|
+
abortSignal: options.abortSignal,
|
|
1041
|
+
maxRetries: options.maxRetries
|
|
1042
|
+
});
|
|
1043
|
+
if (this.cache) {
|
|
1044
|
+
await this.cache.set(key, result);
|
|
1045
|
+
}
|
|
1046
|
+
return result;
|
|
1047
|
+
}
|
|
1048
|
+
/** Embeds many values (the SDK batches automatically). */
|
|
1049
|
+
async embedMany(values, options = {}) {
|
|
1050
|
+
return ai.embedMany({
|
|
1051
|
+
model: this.providers.getEmbeddingModel(options.model),
|
|
1052
|
+
values,
|
|
1053
|
+
abortSignal: options.abortSignal,
|
|
1054
|
+
maxRetries: options.maxRetries
|
|
1055
|
+
});
|
|
1056
|
+
}
|
|
1057
|
+
};
|
|
1058
|
+
exports.EmbeddingsService = _ts_decorate9([
|
|
1059
|
+
common.Injectable(),
|
|
1060
|
+
_ts_param5(1, common.Optional()),
|
|
1061
|
+
_ts_param5(1, common.Inject(AI_CACHE)),
|
|
1062
|
+
_ts_metadata8("design:type", Function),
|
|
1063
|
+
_ts_metadata8("design:paramtypes", [
|
|
1064
|
+
typeof exports.ProviderRegistry === "undefined" ? Object : exports.ProviderRegistry,
|
|
1065
|
+
typeof AiCache === "undefined" ? Object : AiCache
|
|
1066
|
+
])
|
|
1067
|
+
], exports.EmbeddingsService);
|
|
1068
|
+
|
|
1069
|
+
// src/memory/semantic/semantic-memory.service.ts
|
|
1070
|
+
function _ts_decorate10(decorators, target, key, desc) {
|
|
1071
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1072
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
1073
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
1074
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
1075
|
+
}
|
|
1076
|
+
__name(_ts_decorate10, "_ts_decorate");
|
|
1077
|
+
function _ts_metadata9(k, v) {
|
|
1078
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
1079
|
+
}
|
|
1080
|
+
__name(_ts_metadata9, "_ts_metadata");
|
|
1081
|
+
function _ts_param6(paramIndex, decorator) {
|
|
1082
|
+
return function(target, key) {
|
|
1083
|
+
decorator(target, key, paramIndex);
|
|
1084
|
+
};
|
|
1085
|
+
}
|
|
1086
|
+
__name(_ts_param6, "_ts_param");
|
|
1087
|
+
exports.SemanticMemory = class SemanticMemory {
|
|
1088
|
+
static {
|
|
1089
|
+
__name(this, "SemanticMemory");
|
|
1090
|
+
}
|
|
1091
|
+
embeddings;
|
|
1092
|
+
store;
|
|
1093
|
+
ai;
|
|
1094
|
+
constructor(embeddings, store, ai) {
|
|
1095
|
+
this.embeddings = embeddings;
|
|
1096
|
+
this.store = store;
|
|
1097
|
+
this.ai = ai;
|
|
1098
|
+
}
|
|
1099
|
+
/** Embeds and stores a snippet under a conversation. */
|
|
1100
|
+
async remember(conversationId, text, options = {}) {
|
|
1101
|
+
const { embedding } = await this.embeddings.embed(text, {
|
|
1102
|
+
model: options.model
|
|
1103
|
+
});
|
|
1104
|
+
await this.store.upsert([
|
|
1105
|
+
{
|
|
1106
|
+
id: `mem:${conversationId}:${hash(text)}`,
|
|
1107
|
+
content: text,
|
|
1108
|
+
embedding,
|
|
1109
|
+
metadata: {
|
|
1110
|
+
conversationId,
|
|
1111
|
+
kind: "memory",
|
|
1112
|
+
...options.metadata
|
|
1113
|
+
}
|
|
1114
|
+
}
|
|
1115
|
+
]);
|
|
1116
|
+
}
|
|
1117
|
+
/** Returns the most relevant stored snippets for a query. */
|
|
1118
|
+
async recall(conversationId, query, options = {}) {
|
|
1119
|
+
const { embedding } = await this.embeddings.embed(query, {
|
|
1120
|
+
model: options.model
|
|
1121
|
+
});
|
|
1122
|
+
return this.store.query(embedding, {
|
|
1123
|
+
topK: options.topK ?? 4,
|
|
1124
|
+
filter: {
|
|
1125
|
+
conversationId,
|
|
1126
|
+
kind: "memory"
|
|
1127
|
+
}
|
|
1128
|
+
});
|
|
1129
|
+
}
|
|
1130
|
+
/**
|
|
1131
|
+
* Summarizes messages with the LLM (requires `AiService`), then stores the
|
|
1132
|
+
* summary as a memory snippet. Returns the stored text.
|
|
1133
|
+
*/
|
|
1134
|
+
async rememberConversation(conversationId, input, options = {}) {
|
|
1135
|
+
const text = options.summarize ? await this.summarize(input, options.model) : messagesToText(input);
|
|
1136
|
+
await this.remember(conversationId, text, {
|
|
1137
|
+
model: options.model
|
|
1138
|
+
});
|
|
1139
|
+
return text;
|
|
1140
|
+
}
|
|
1141
|
+
/** Summarizes messages into a compact string via the LLM. */
|
|
1142
|
+
async summarize(input, model) {
|
|
1143
|
+
if (!this.ai) {
|
|
1144
|
+
throw new Error("SemanticMemory.summarize requires AiService.");
|
|
1145
|
+
}
|
|
1146
|
+
const { text } = await this.ai.generateText({
|
|
1147
|
+
model,
|
|
1148
|
+
prompt: `Summarize the following conversation concisely:
|
|
1149
|
+
|
|
1150
|
+
${messagesToText(input)}`
|
|
1151
|
+
});
|
|
1152
|
+
return text;
|
|
1153
|
+
}
|
|
1154
|
+
};
|
|
1155
|
+
exports.SemanticMemory = _ts_decorate10([
|
|
1156
|
+
common.Injectable(),
|
|
1157
|
+
_ts_param6(1, common.Inject(VECTOR_STORE)),
|
|
1158
|
+
_ts_param6(2, common.Optional()),
|
|
1159
|
+
_ts_metadata9("design:type", Function),
|
|
1160
|
+
_ts_metadata9("design:paramtypes", [
|
|
1161
|
+
typeof exports.EmbeddingsService === "undefined" ? Object : exports.EmbeddingsService,
|
|
1162
|
+
typeof VectorStore === "undefined" ? Object : VectorStore,
|
|
1163
|
+
typeof exports.AiService === "undefined" ? Object : exports.AiService
|
|
1164
|
+
])
|
|
1165
|
+
], exports.SemanticMemory);
|
|
1166
|
+
function messagesToText(input) {
|
|
1167
|
+
return toMessages(input).map((m) => {
|
|
1168
|
+
const content = m.content;
|
|
1169
|
+
if (typeof content === "string") {
|
|
1170
|
+
return `${m.role}: ${content}`;
|
|
1171
|
+
}
|
|
1172
|
+
if (Array.isArray(content)) {
|
|
1173
|
+
return `${m.role}: ${content.map((p) => p && typeof p.text === "string" ? p.text : "").join(" ")}`;
|
|
1174
|
+
}
|
|
1175
|
+
return "";
|
|
1176
|
+
}).join("\n");
|
|
1177
|
+
}
|
|
1178
|
+
__name(messagesToText, "messagesToText");
|
|
1179
|
+
function hash(text) {
|
|
1180
|
+
let h = 5381;
|
|
1181
|
+
for (let i = 0; i < text.length; i++) {
|
|
1182
|
+
h = h * 33 ^ text.charCodeAt(i);
|
|
1183
|
+
}
|
|
1184
|
+
return (h >>> 0).toString(36);
|
|
1185
|
+
}
|
|
1186
|
+
__name(hash, "hash");
|
|
1187
|
+
|
|
1188
|
+
// src/agent/agent-executor.service.ts
|
|
1189
|
+
function _ts_decorate11(decorators, target, key, desc) {
|
|
1190
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1191
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
1192
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
1193
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
1194
|
+
}
|
|
1195
|
+
__name(_ts_decorate11, "_ts_decorate");
|
|
1196
|
+
function _ts_metadata10(k, v) {
|
|
1197
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
1198
|
+
}
|
|
1199
|
+
__name(_ts_metadata10, "_ts_metadata");
|
|
1200
|
+
function _ts_param7(paramIndex, decorator) {
|
|
1201
|
+
return function(target, key) {
|
|
1202
|
+
decorator(target, key, paramIndex);
|
|
1203
|
+
};
|
|
1204
|
+
}
|
|
1205
|
+
__name(_ts_param7, "_ts_param");
|
|
1206
|
+
exports.AgentExecutorService = class AgentExecutorService {
|
|
1207
|
+
static {
|
|
1208
|
+
__name(this, "AgentExecutorService");
|
|
1209
|
+
}
|
|
1210
|
+
providers;
|
|
1211
|
+
toolRegistry;
|
|
1212
|
+
store;
|
|
1213
|
+
options;
|
|
1214
|
+
events;
|
|
1215
|
+
guardrails;
|
|
1216
|
+
prompts;
|
|
1217
|
+
usageTracker;
|
|
1218
|
+
semanticMemory;
|
|
1219
|
+
constructor(providers, toolRegistry, store, options, events, guardrails, prompts, usageTracker, semanticMemory) {
|
|
1220
|
+
this.providers = providers;
|
|
1221
|
+
this.toolRegistry = toolRegistry;
|
|
1222
|
+
this.store = store;
|
|
1223
|
+
this.options = options;
|
|
1224
|
+
this.events = events;
|
|
1225
|
+
this.guardrails = guardrails;
|
|
1226
|
+
this.prompts = prompts;
|
|
1227
|
+
this.usageTracker = usageTracker;
|
|
1228
|
+
this.semanticMemory = semanticMemory;
|
|
1229
|
+
}
|
|
1230
|
+
/** Runs an agent to completion and returns its result. */
|
|
1231
|
+
async run(agent, input, opts = {}) {
|
|
1232
|
+
const meta = this.readMetadata(agent);
|
|
1233
|
+
const agentName = agent.constructor?.name ?? "AiAgent";
|
|
1234
|
+
const model = this.providers.getLanguageModel(opts.model ?? meta.model);
|
|
1235
|
+
const system = await this.resolveSystemWithRecall(opts, meta, input);
|
|
1236
|
+
const schema = opts.schema ?? meta.output;
|
|
1237
|
+
const maxSteps = this.resolveMaxSteps(opts, meta);
|
|
1238
|
+
const newMessages = toMessages(input);
|
|
1239
|
+
const history = await this.loadHistory(opts.conversationId);
|
|
1240
|
+
const ctx = {
|
|
1241
|
+
agent: agentName,
|
|
1242
|
+
messages: [
|
|
1243
|
+
...history,
|
|
1244
|
+
...newMessages
|
|
1245
|
+
],
|
|
1246
|
+
options: opts
|
|
1247
|
+
};
|
|
1248
|
+
this.events?.emit(AI_EVENTS.agentRunStart, {
|
|
1249
|
+
agent: agentName,
|
|
1250
|
+
input,
|
|
1251
|
+
options: opts
|
|
1252
|
+
});
|
|
1253
|
+
try {
|
|
1254
|
+
await this.guardrails?.runBeforeRun(ctx);
|
|
1255
|
+
const result = schema ? await this.runObject(model, system, ctx.messages, schema, opts, newMessages) : await this.runText(model, system, ctx.messages, meta, maxSteps, opts, newMessages);
|
|
1256
|
+
this.usageTracker?.record({
|
|
1257
|
+
model: model.modelId ?? "unknown",
|
|
1258
|
+
usage: result.usage,
|
|
1259
|
+
conversationId: opts.conversationId,
|
|
1260
|
+
agent: agentName
|
|
1261
|
+
});
|
|
1262
|
+
await this.guardrails?.runAfterRun(ctx, result);
|
|
1263
|
+
this.events?.emit(AI_EVENTS.agentRunFinish, {
|
|
1264
|
+
agent: agentName,
|
|
1265
|
+
result
|
|
1266
|
+
});
|
|
1267
|
+
return result;
|
|
1268
|
+
} catch (error) {
|
|
1269
|
+
this.events?.emit(AI_EVENTS.agentRunError, {
|
|
1270
|
+
agent: agentName,
|
|
1271
|
+
error
|
|
1272
|
+
});
|
|
1273
|
+
throw error;
|
|
1274
|
+
}
|
|
1275
|
+
}
|
|
1276
|
+
async runObject(model, system, messages, schema, opts, newMessages) {
|
|
1277
|
+
const result = await ai.generateObject({
|
|
1278
|
+
model,
|
|
1279
|
+
system,
|
|
1280
|
+
messages,
|
|
1281
|
+
schema,
|
|
1282
|
+
abortSignal: opts.abortSignal,
|
|
1283
|
+
temperature: opts.temperature,
|
|
1284
|
+
maxRetries: opts.maxRetries ?? this.options.maxRetries,
|
|
1285
|
+
experimental_telemetry: this.telemetry()
|
|
1286
|
+
});
|
|
1287
|
+
await this.persist(opts.conversationId, newMessages, [
|
|
1288
|
+
{
|
|
1289
|
+
role: "assistant",
|
|
1290
|
+
content: JSON.stringify(result.object)
|
|
1291
|
+
}
|
|
1292
|
+
]);
|
|
1293
|
+
return {
|
|
1294
|
+
text: "",
|
|
1295
|
+
object: result.object,
|
|
1296
|
+
usage: result.usage,
|
|
1297
|
+
finishReason: result.finishReason,
|
|
1298
|
+
messages: []
|
|
1299
|
+
};
|
|
1300
|
+
}
|
|
1301
|
+
async runText(model, system, messages, meta, maxSteps, opts, newMessages) {
|
|
1302
|
+
const result = await ai.generateText({
|
|
1303
|
+
model,
|
|
1304
|
+
system,
|
|
1305
|
+
messages,
|
|
1306
|
+
tools: this.toolRegistry.buildToolSet(meta.tools),
|
|
1307
|
+
stopWhen: ai.stepCountIs(maxSteps),
|
|
1308
|
+
abortSignal: opts.abortSignal,
|
|
1309
|
+
temperature: opts.temperature,
|
|
1310
|
+
maxRetries: opts.maxRetries ?? this.options.maxRetries,
|
|
1311
|
+
experimental_telemetry: this.telemetry()
|
|
1312
|
+
});
|
|
1313
|
+
await this.persist(opts.conversationId, newMessages, result.response.messages);
|
|
1314
|
+
return {
|
|
1315
|
+
text: result.text,
|
|
1316
|
+
steps: result.steps,
|
|
1317
|
+
toolCalls: result.toolCalls,
|
|
1318
|
+
usage: result.totalUsage,
|
|
1319
|
+
finishReason: result.finishReason,
|
|
1320
|
+
messages: result.response.messages
|
|
1321
|
+
};
|
|
1322
|
+
}
|
|
1323
|
+
/**
|
|
1324
|
+
* Streams an agent's response. Returns the raw Vercel stream result so
|
|
1325
|
+
* controllers can pipe it to an HTTP response or iterate `textStream`.
|
|
1326
|
+
* Conversation persistence happens on stream finish.
|
|
1327
|
+
*/
|
|
1328
|
+
stream(agent, input, opts = {}) {
|
|
1329
|
+
const meta = this.readMetadata(agent);
|
|
1330
|
+
const agentName = agent.constructor?.name ?? "AiAgent";
|
|
1331
|
+
const model = this.providers.getLanguageModel(opts.model ?? meta.model);
|
|
1332
|
+
const system = this.resolveSystem(opts, meta);
|
|
1333
|
+
const schema = opts.schema ?? meta.output;
|
|
1334
|
+
const maxSteps = this.resolveMaxSteps(opts, meta);
|
|
1335
|
+
const newMessages = toMessages(input);
|
|
1336
|
+
this.events?.emit(AI_EVENTS.agentRunStart, {
|
|
1337
|
+
agent: agentName,
|
|
1338
|
+
input,
|
|
1339
|
+
options: opts
|
|
1340
|
+
});
|
|
1341
|
+
if (schema) {
|
|
1342
|
+
return ai.streamObject({
|
|
1343
|
+
model,
|
|
1344
|
+
system,
|
|
1345
|
+
messages: newMessages,
|
|
1346
|
+
schema,
|
|
1347
|
+
abortSignal: opts.abortSignal,
|
|
1348
|
+
temperature: opts.temperature,
|
|
1349
|
+
experimental_telemetry: this.telemetry(),
|
|
1350
|
+
onFinish: /* @__PURE__ */ __name(async ({ object }) => {
|
|
1351
|
+
if (object !== void 0) {
|
|
1352
|
+
await this.persist(opts.conversationId, newMessages, [
|
|
1353
|
+
{
|
|
1354
|
+
role: "assistant",
|
|
1355
|
+
content: JSON.stringify(object)
|
|
1356
|
+
}
|
|
1357
|
+
]);
|
|
1358
|
+
}
|
|
1359
|
+
this.events?.emit(AI_EVENTS.streamFinish, {
|
|
1360
|
+
agent: agentName
|
|
1361
|
+
});
|
|
1362
|
+
}, "onFinish")
|
|
1363
|
+
});
|
|
1364
|
+
}
|
|
1365
|
+
return ai.streamText({
|
|
1366
|
+
model,
|
|
1367
|
+
system,
|
|
1368
|
+
messages: newMessages,
|
|
1369
|
+
tools: this.toolRegistry.buildToolSet(meta.tools),
|
|
1370
|
+
stopWhen: ai.stepCountIs(maxSteps),
|
|
1371
|
+
abortSignal: opts.abortSignal,
|
|
1372
|
+
temperature: opts.temperature,
|
|
1373
|
+
maxRetries: opts.maxRetries ?? this.options.maxRetries,
|
|
1374
|
+
experimental_telemetry: this.telemetry(),
|
|
1375
|
+
onFinish: /* @__PURE__ */ __name(async ({ response }) => {
|
|
1376
|
+
await this.persist(opts.conversationId, newMessages, response.messages);
|
|
1377
|
+
this.events?.emit(AI_EVENTS.streamFinish, {
|
|
1378
|
+
agent: agentName
|
|
1379
|
+
});
|
|
1380
|
+
}, "onFinish")
|
|
1381
|
+
});
|
|
1382
|
+
}
|
|
1383
|
+
/** Resolves the system prompt and prepends recalled memory when requested. */
|
|
1384
|
+
async resolveSystemWithRecall(opts, meta, input) {
|
|
1385
|
+
let system = this.resolveSystem(opts, meta);
|
|
1386
|
+
if (opts.recall && opts.conversationId && this.semanticMemory) {
|
|
1387
|
+
const query = opts.recall.query ?? (typeof input === "string" ? input : "");
|
|
1388
|
+
if (query) {
|
|
1389
|
+
const snippets = await this.semanticMemory.recall(opts.conversationId, query, {
|
|
1390
|
+
topK: opts.recall.topK
|
|
1391
|
+
});
|
|
1392
|
+
if (snippets.length > 0) {
|
|
1393
|
+
const context = snippets.map((s) => s.content).join("\n");
|
|
1394
|
+
system = [
|
|
1395
|
+
system,
|
|
1396
|
+
`Relevant context from memory:
|
|
1397
|
+
${context}`
|
|
1398
|
+
].filter(Boolean).join("\n\n");
|
|
1399
|
+
}
|
|
1400
|
+
}
|
|
1401
|
+
}
|
|
1402
|
+
return system;
|
|
1403
|
+
}
|
|
1404
|
+
resolveSystem(opts, meta) {
|
|
1405
|
+
if (opts.systemPrompt) {
|
|
1406
|
+
if (!this.prompts) {
|
|
1407
|
+
throw new Error("systemPrompt requires the PromptRegistry (AiModule must be imported).");
|
|
1408
|
+
}
|
|
1409
|
+
return this.prompts.render(opts.systemPrompt.name, opts.systemPrompt.vars, {
|
|
1410
|
+
version: opts.systemPrompt.version
|
|
1411
|
+
});
|
|
1412
|
+
}
|
|
1413
|
+
return opts.system ?? meta.system;
|
|
1414
|
+
}
|
|
1415
|
+
telemetry() {
|
|
1416
|
+
const t = this.options.telemetry;
|
|
1417
|
+
if (!t?.isEnabled) {
|
|
1418
|
+
return void 0;
|
|
1419
|
+
}
|
|
1420
|
+
return {
|
|
1421
|
+
isEnabled: true,
|
|
1422
|
+
functionId: t.functionId
|
|
1423
|
+
};
|
|
1424
|
+
}
|
|
1425
|
+
readMetadata(agent) {
|
|
1426
|
+
const ctor = agent.constructor;
|
|
1427
|
+
return Reflect.getMetadata(AGENT_METADATA, ctor) ?? {};
|
|
1428
|
+
}
|
|
1429
|
+
resolveMaxSteps(opts, meta) {
|
|
1430
|
+
return opts.maxSteps ?? meta.maxSteps ?? this.options.defaultMaxSteps ?? DEFAULT_MAX_STEPS;
|
|
1431
|
+
}
|
|
1432
|
+
async loadHistory(conversationId) {
|
|
1433
|
+
if (!conversationId) {
|
|
1434
|
+
return [];
|
|
1435
|
+
}
|
|
1436
|
+
return this.store.load(conversationId);
|
|
1437
|
+
}
|
|
1438
|
+
async persist(conversationId, userMessages, responseMessages) {
|
|
1439
|
+
if (!conversationId) {
|
|
1440
|
+
return;
|
|
1441
|
+
}
|
|
1442
|
+
await this.store.append(conversationId, [
|
|
1443
|
+
...userMessages,
|
|
1444
|
+
...responseMessages
|
|
1445
|
+
]);
|
|
1446
|
+
}
|
|
1447
|
+
};
|
|
1448
|
+
exports.AgentExecutorService = _ts_decorate11([
|
|
1449
|
+
common.Injectable(),
|
|
1450
|
+
_ts_param7(2, common.Inject(CONVERSATION_STORE)),
|
|
1451
|
+
_ts_param7(3, common.Inject(AI_MODULE_OPTIONS)),
|
|
1452
|
+
_ts_param7(4, common.Optional()),
|
|
1453
|
+
_ts_param7(5, common.Optional()),
|
|
1454
|
+
_ts_param7(6, common.Optional()),
|
|
1455
|
+
_ts_param7(7, common.Optional()),
|
|
1456
|
+
_ts_param7(8, common.Optional()),
|
|
1457
|
+
_ts_metadata10("design:type", Function),
|
|
1458
|
+
_ts_metadata10("design:paramtypes", [
|
|
1459
|
+
typeof exports.ProviderRegistry === "undefined" ? Object : exports.ProviderRegistry,
|
|
1460
|
+
typeof exports.ToolRegistry === "undefined" ? Object : exports.ToolRegistry,
|
|
1461
|
+
typeof ConversationStore === "undefined" ? Object : ConversationStore,
|
|
1462
|
+
typeof AiModuleOptions === "undefined" ? Object : AiModuleOptions,
|
|
1463
|
+
typeof exports.AiEventEmitter === "undefined" ? Object : exports.AiEventEmitter,
|
|
1464
|
+
typeof exports.GuardrailRegistry === "undefined" ? Object : exports.GuardrailRegistry,
|
|
1465
|
+
typeof exports.PromptRegistry === "undefined" ? Object : exports.PromptRegistry,
|
|
1466
|
+
typeof exports.UsageTracker === "undefined" ? Object : exports.UsageTracker,
|
|
1467
|
+
typeof exports.SemanticMemory === "undefined" ? Object : exports.SemanticMemory
|
|
1468
|
+
])
|
|
1469
|
+
], exports.AgentExecutorService);
|
|
1470
|
+
function _ts_decorate12(decorators, target, key, desc) {
|
|
1471
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1472
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
1473
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
1474
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
1475
|
+
}
|
|
1476
|
+
__name(_ts_decorate12, "_ts_decorate");
|
|
1477
|
+
exports.InMemoryConversationStore = class InMemoryConversationStore {
|
|
1478
|
+
static {
|
|
1479
|
+
__name(this, "InMemoryConversationStore");
|
|
1480
|
+
}
|
|
1481
|
+
conversations = /* @__PURE__ */ new Map();
|
|
1482
|
+
async load(conversationId) {
|
|
1483
|
+
return [
|
|
1484
|
+
...this.conversations.get(conversationId) ?? []
|
|
1485
|
+
];
|
|
1486
|
+
}
|
|
1487
|
+
async append(conversationId, messages) {
|
|
1488
|
+
const existing = this.conversations.get(conversationId) ?? [];
|
|
1489
|
+
this.conversations.set(conversationId, [
|
|
1490
|
+
...existing,
|
|
1491
|
+
...messages
|
|
1492
|
+
]);
|
|
1493
|
+
}
|
|
1494
|
+
async clear(conversationId) {
|
|
1495
|
+
this.conversations.delete(conversationId);
|
|
1496
|
+
}
|
|
1497
|
+
};
|
|
1498
|
+
exports.InMemoryConversationStore = _ts_decorate12([
|
|
1499
|
+
common.Injectable()
|
|
1500
|
+
], exports.InMemoryConversationStore);
|
|
1501
|
+
function _ts_decorate13(decorators, target, key, desc) {
|
|
1502
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1503
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
1504
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
1505
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
1506
|
+
}
|
|
1507
|
+
__name(_ts_decorate13, "_ts_decorate");
|
|
1508
|
+
function _ts_metadata11(k, v) {
|
|
1509
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
1510
|
+
}
|
|
1511
|
+
__name(_ts_metadata11, "_ts_metadata");
|
|
1512
|
+
exports.ImageService = class ImageService {
|
|
1513
|
+
static {
|
|
1514
|
+
__name(this, "ImageService");
|
|
1515
|
+
}
|
|
1516
|
+
providers;
|
|
1517
|
+
constructor(providers) {
|
|
1518
|
+
this.providers = providers;
|
|
1519
|
+
}
|
|
1520
|
+
generate(prompt, options = {}) {
|
|
1521
|
+
const { model, ...rest } = options;
|
|
1522
|
+
return ai.generateImage({
|
|
1523
|
+
model: this.providers.getImageModel(model),
|
|
1524
|
+
prompt,
|
|
1525
|
+
...rest
|
|
1526
|
+
});
|
|
1527
|
+
}
|
|
1528
|
+
};
|
|
1529
|
+
exports.ImageService = _ts_decorate13([
|
|
1530
|
+
common.Injectable(),
|
|
1531
|
+
_ts_metadata11("design:type", Function),
|
|
1532
|
+
_ts_metadata11("design:paramtypes", [
|
|
1533
|
+
typeof exports.ProviderRegistry === "undefined" ? Object : exports.ProviderRegistry
|
|
1534
|
+
])
|
|
1535
|
+
], exports.ImageService);
|
|
1536
|
+
function _ts_decorate14(decorators, target, key, desc) {
|
|
1537
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1538
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
1539
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
1540
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
1541
|
+
}
|
|
1542
|
+
__name(_ts_decorate14, "_ts_decorate");
|
|
1543
|
+
function _ts_metadata12(k, v) {
|
|
1544
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
1545
|
+
}
|
|
1546
|
+
__name(_ts_metadata12, "_ts_metadata");
|
|
1547
|
+
exports.SpeechService = class SpeechService {
|
|
1548
|
+
static {
|
|
1549
|
+
__name(this, "SpeechService");
|
|
1550
|
+
}
|
|
1551
|
+
providers;
|
|
1552
|
+
constructor(providers) {
|
|
1553
|
+
this.providers = providers;
|
|
1554
|
+
}
|
|
1555
|
+
generate(text, options = {}) {
|
|
1556
|
+
const { model, ...rest } = options;
|
|
1557
|
+
return ai.experimental_generateSpeech({
|
|
1558
|
+
model: this.providers.getSpeechModel(model),
|
|
1559
|
+
text,
|
|
1560
|
+
...rest
|
|
1561
|
+
});
|
|
1562
|
+
}
|
|
1563
|
+
};
|
|
1564
|
+
exports.SpeechService = _ts_decorate14([
|
|
1565
|
+
common.Injectable(),
|
|
1566
|
+
_ts_metadata12("design:type", Function),
|
|
1567
|
+
_ts_metadata12("design:paramtypes", [
|
|
1568
|
+
typeof exports.ProviderRegistry === "undefined" ? Object : exports.ProviderRegistry
|
|
1569
|
+
])
|
|
1570
|
+
], exports.SpeechService);
|
|
1571
|
+
function _ts_decorate15(decorators, target, key, desc) {
|
|
1572
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1573
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
1574
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
1575
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
1576
|
+
}
|
|
1577
|
+
__name(_ts_decorate15, "_ts_decorate");
|
|
1578
|
+
function _ts_metadata13(k, v) {
|
|
1579
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
1580
|
+
}
|
|
1581
|
+
__name(_ts_metadata13, "_ts_metadata");
|
|
1582
|
+
exports.TranscriptionService = class TranscriptionService {
|
|
1583
|
+
static {
|
|
1584
|
+
__name(this, "TranscriptionService");
|
|
1585
|
+
}
|
|
1586
|
+
providers;
|
|
1587
|
+
constructor(providers) {
|
|
1588
|
+
this.providers = providers;
|
|
1589
|
+
}
|
|
1590
|
+
transcribe(audio, options = {}) {
|
|
1591
|
+
const { model, ...rest } = options;
|
|
1592
|
+
return ai.experimental_transcribe({
|
|
1593
|
+
model: this.providers.getTranscriptionModel(model),
|
|
1594
|
+
audio,
|
|
1595
|
+
...rest
|
|
1596
|
+
});
|
|
1597
|
+
}
|
|
1598
|
+
};
|
|
1599
|
+
exports.TranscriptionService = _ts_decorate15([
|
|
1600
|
+
common.Injectable(),
|
|
1601
|
+
_ts_metadata13("design:type", Function),
|
|
1602
|
+
_ts_metadata13("design:paramtypes", [
|
|
1603
|
+
typeof exports.ProviderRegistry === "undefined" ? Object : exports.ProviderRegistry
|
|
1604
|
+
])
|
|
1605
|
+
], exports.TranscriptionService);
|
|
1606
|
+
function _ts_decorate16(decorators, target, key, desc) {
|
|
1607
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1608
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
1609
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
1610
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
1611
|
+
}
|
|
1612
|
+
__name(_ts_decorate16, "_ts_decorate");
|
|
1613
|
+
function _ts_metadata14(k, v) {
|
|
1614
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
1615
|
+
}
|
|
1616
|
+
__name(_ts_metadata14, "_ts_metadata");
|
|
1617
|
+
function _ts_param8(paramIndex, decorator) {
|
|
1618
|
+
return function(target, key) {
|
|
1619
|
+
decorator(target, key, paramIndex);
|
|
1620
|
+
};
|
|
1621
|
+
}
|
|
1622
|
+
__name(_ts_param8, "_ts_param");
|
|
1623
|
+
exports.RagService = class RagService {
|
|
1624
|
+
static {
|
|
1625
|
+
__name(this, "RagService");
|
|
1626
|
+
}
|
|
1627
|
+
embeddings;
|
|
1628
|
+
store;
|
|
1629
|
+
defaultReranker;
|
|
1630
|
+
constructor(embeddings, store, defaultReranker) {
|
|
1631
|
+
this.embeddings = embeddings;
|
|
1632
|
+
this.store = store;
|
|
1633
|
+
this.defaultReranker = defaultReranker;
|
|
1634
|
+
}
|
|
1635
|
+
/** Chunks, embeds, and upserts items into the vector store. */
|
|
1636
|
+
async ingest(items, options = {}) {
|
|
1637
|
+
const chunkSize = options.chunkSize ?? 1e3;
|
|
1638
|
+
const overlap2 = options.chunkOverlap ?? 100;
|
|
1639
|
+
const chunks = [];
|
|
1640
|
+
items.forEach((item, index) => {
|
|
1641
|
+
const baseId = item.id ?? `doc-${index}`;
|
|
1642
|
+
splitText(item.content, chunkSize, overlap2).forEach((text, chunkIndex) => {
|
|
1643
|
+
chunks.push({
|
|
1644
|
+
id: `${baseId}#${chunkIndex}`,
|
|
1645
|
+
content: text,
|
|
1646
|
+
metadata: item.metadata
|
|
1647
|
+
});
|
|
1648
|
+
});
|
|
1649
|
+
});
|
|
1650
|
+
if (chunks.length === 0) {
|
|
1651
|
+
return;
|
|
1652
|
+
}
|
|
1653
|
+
const { embeddings } = await this.embeddings.embedMany(chunks.map((c) => c.content), {
|
|
1654
|
+
model: options.model
|
|
1655
|
+
});
|
|
1656
|
+
const documents = chunks.map((chunk, i) => ({
|
|
1657
|
+
...chunk,
|
|
1658
|
+
embedding: embeddings[i]
|
|
1659
|
+
}));
|
|
1660
|
+
await this.store.upsert(documents);
|
|
1661
|
+
}
|
|
1662
|
+
/** Embeds `query` and returns the most similar stored chunks. */
|
|
1663
|
+
async retrieve(query, options = {}) {
|
|
1664
|
+
const { embedding } = await this.embeddings.embed(query, {
|
|
1665
|
+
model: options.model
|
|
1666
|
+
});
|
|
1667
|
+
const topK = options.topK ?? 4;
|
|
1668
|
+
const reranker = options.rerank === true ? this.defaultReranker : options.rerank || void 0;
|
|
1669
|
+
const fetchK = reranker ? options.fetchK ?? topK * 4 : topK;
|
|
1670
|
+
const results = await this.store.query(embedding, {
|
|
1671
|
+
topK: fetchK,
|
|
1672
|
+
filter: options.filter
|
|
1673
|
+
});
|
|
1674
|
+
if (reranker) {
|
|
1675
|
+
return reranker.rerank(query, results, topK);
|
|
1676
|
+
}
|
|
1677
|
+
return results.slice(0, topK);
|
|
1678
|
+
}
|
|
1679
|
+
};
|
|
1680
|
+
exports.RagService = _ts_decorate16([
|
|
1681
|
+
common.Injectable(),
|
|
1682
|
+
_ts_param8(1, common.Inject(VECTOR_STORE)),
|
|
1683
|
+
_ts_param8(2, common.Optional()),
|
|
1684
|
+
_ts_param8(2, common.Inject(RERANKER)),
|
|
1685
|
+
_ts_metadata14("design:type", Function),
|
|
1686
|
+
_ts_metadata14("design:paramtypes", [
|
|
1687
|
+
typeof exports.EmbeddingsService === "undefined" ? Object : exports.EmbeddingsService,
|
|
1688
|
+
typeof VectorStore === "undefined" ? Object : VectorStore,
|
|
1689
|
+
typeof Reranker === "undefined" ? Object : Reranker
|
|
1690
|
+
])
|
|
1691
|
+
], exports.RagService);
|
|
1692
|
+
function splitText(text, chunkSize, overlap2) {
|
|
1693
|
+
if (chunkSize <= 0 || text.length <= chunkSize) {
|
|
1694
|
+
return text.length > 0 ? [
|
|
1695
|
+
text
|
|
1696
|
+
] : [];
|
|
1697
|
+
}
|
|
1698
|
+
const step = Math.max(1, chunkSize - overlap2);
|
|
1699
|
+
const chunks = [];
|
|
1700
|
+
for (let start = 0; start < text.length; start += step) {
|
|
1701
|
+
chunks.push(text.slice(start, start + chunkSize));
|
|
1702
|
+
if (start + chunkSize >= text.length) {
|
|
1703
|
+
break;
|
|
1704
|
+
}
|
|
1705
|
+
}
|
|
1706
|
+
return chunks;
|
|
1707
|
+
}
|
|
1708
|
+
__name(splitText, "splitText");
|
|
1709
|
+
function _ts_decorate17(decorators, target, key, desc) {
|
|
1710
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1711
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
1712
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
1713
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
1714
|
+
}
|
|
1715
|
+
__name(_ts_decorate17, "_ts_decorate");
|
|
1716
|
+
exports.InMemoryVectorStore = class InMemoryVectorStore {
|
|
1717
|
+
static {
|
|
1718
|
+
__name(this, "InMemoryVectorStore");
|
|
1719
|
+
}
|
|
1720
|
+
documents = /* @__PURE__ */ new Map();
|
|
1721
|
+
async upsert(documents) {
|
|
1722
|
+
for (const doc of documents) {
|
|
1723
|
+
if (!doc.embedding) {
|
|
1724
|
+
throw new Error(`Document "${doc.id}" has no embedding. InMemoryVectorStore requires precomputed embeddings (use RagService.ingest).`);
|
|
1725
|
+
}
|
|
1726
|
+
this.documents.set(doc.id, doc);
|
|
1727
|
+
}
|
|
1728
|
+
}
|
|
1729
|
+
async query(embedding, options = {}) {
|
|
1730
|
+
const topK = options.topK ?? 4;
|
|
1731
|
+
const filter = options.filter;
|
|
1732
|
+
const scored = [];
|
|
1733
|
+
for (const doc of this.documents.values()) {
|
|
1734
|
+
if (filter && !this.matchesFilter(doc, filter)) {
|
|
1735
|
+
continue;
|
|
1736
|
+
}
|
|
1737
|
+
scored.push({
|
|
1738
|
+
id: doc.id,
|
|
1739
|
+
content: doc.content,
|
|
1740
|
+
score: ai.cosineSimilarity(embedding, doc.embedding),
|
|
1741
|
+
metadata: doc.metadata
|
|
1742
|
+
});
|
|
1743
|
+
}
|
|
1744
|
+
return scored.sort((a, b) => b.score - a.score).slice(0, topK);
|
|
1745
|
+
}
|
|
1746
|
+
async delete(ids) {
|
|
1747
|
+
for (const id of ids) {
|
|
1748
|
+
this.documents.delete(id);
|
|
1749
|
+
}
|
|
1750
|
+
}
|
|
1751
|
+
async clear() {
|
|
1752
|
+
this.documents.clear();
|
|
1753
|
+
}
|
|
1754
|
+
matchesFilter(doc, filter) {
|
|
1755
|
+
return Object.entries(filter).every(([key, value]) => doc.metadata?.[key] === value);
|
|
1756
|
+
}
|
|
1757
|
+
};
|
|
1758
|
+
exports.InMemoryVectorStore = _ts_decorate17([
|
|
1759
|
+
common.Injectable()
|
|
1760
|
+
], exports.InMemoryVectorStore);
|
|
1761
|
+
function _ts_decorate18(decorators, target, key, desc) {
|
|
1762
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1763
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
1764
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
1765
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
1766
|
+
}
|
|
1767
|
+
__name(_ts_decorate18, "_ts_decorate");
|
|
1768
|
+
exports.McpService = class McpService {
|
|
1769
|
+
static {
|
|
1770
|
+
__name(this, "McpService");
|
|
1771
|
+
}
|
|
1772
|
+
clients = /* @__PURE__ */ new Map();
|
|
1773
|
+
toolSets = /* @__PURE__ */ new Map();
|
|
1774
|
+
/**
|
|
1775
|
+
* Registers an MCP client under `name`, lists its tools, and builds a
|
|
1776
|
+
* matching AI SDK tool set. Returns the tool set.
|
|
1777
|
+
*/
|
|
1778
|
+
async connect(name, client) {
|
|
1779
|
+
const { tools } = await client.listTools();
|
|
1780
|
+
const set = {};
|
|
1781
|
+
for (const info of tools) {
|
|
1782
|
+
set[info.name] = ai.dynamicTool({
|
|
1783
|
+
description: info.description ?? info.name,
|
|
1784
|
+
inputSchema: ai.jsonSchema(info.inputSchema),
|
|
1785
|
+
execute: /* @__PURE__ */ __name(async (args) => {
|
|
1786
|
+
const result = await client.callTool({
|
|
1787
|
+
name: info.name,
|
|
1788
|
+
arguments: args ?? {}
|
|
1789
|
+
});
|
|
1790
|
+
return extractText(result);
|
|
1791
|
+
}, "execute")
|
|
1792
|
+
});
|
|
1793
|
+
}
|
|
1794
|
+
this.clients.set(name, client);
|
|
1795
|
+
this.toolSets.set(name, set);
|
|
1796
|
+
return set;
|
|
1797
|
+
}
|
|
1798
|
+
/** Returns the tool set for a connected server (empty if unknown). */
|
|
1799
|
+
getToolSet(name) {
|
|
1800
|
+
return this.toolSets.get(name) ?? {};
|
|
1801
|
+
}
|
|
1802
|
+
/** Returns tool sets for all connected servers, merged. */
|
|
1803
|
+
getAllTools() {
|
|
1804
|
+
return Object.assign({}, ...this.toolSets.values());
|
|
1805
|
+
}
|
|
1806
|
+
async onModuleDestroy() {
|
|
1807
|
+
await this.closeAll();
|
|
1808
|
+
}
|
|
1809
|
+
/** Closes every connected client. */
|
|
1810
|
+
async closeAll() {
|
|
1811
|
+
for (const client of this.clients.values()) {
|
|
1812
|
+
await client.close?.();
|
|
1813
|
+
}
|
|
1814
|
+
this.clients.clear();
|
|
1815
|
+
this.toolSets.clear();
|
|
1816
|
+
}
|
|
1817
|
+
};
|
|
1818
|
+
exports.McpService = _ts_decorate18([
|
|
1819
|
+
common.Injectable()
|
|
1820
|
+
], exports.McpService);
|
|
1821
|
+
function extractText(result) {
|
|
1822
|
+
if (!result.content) {
|
|
1823
|
+
return "";
|
|
1824
|
+
}
|
|
1825
|
+
return result.content.filter((part) => part.type === "text" && typeof part.text === "string").map((part) => part.text).join("\n");
|
|
1826
|
+
}
|
|
1827
|
+
__name(extractText, "extractText");
|
|
1828
|
+
function Guardrail() {
|
|
1829
|
+
return (target) => {
|
|
1830
|
+
Reflect.defineMetadata(GUARDRAIL_METADATA, true, target);
|
|
1831
|
+
common.Injectable()(target);
|
|
1832
|
+
};
|
|
1833
|
+
}
|
|
1834
|
+
__name(Guardrail, "Guardrail");
|
|
1835
|
+
|
|
1836
|
+
// src/usage/budget.guardrail.ts
|
|
1837
|
+
function _ts_decorate19(decorators, target, key, desc) {
|
|
1838
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1839
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
1840
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
1841
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
1842
|
+
}
|
|
1843
|
+
__name(_ts_decorate19, "_ts_decorate");
|
|
1844
|
+
function _ts_metadata15(k, v) {
|
|
1845
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
1846
|
+
}
|
|
1847
|
+
__name(_ts_metadata15, "_ts_metadata");
|
|
1848
|
+
function _ts_param9(paramIndex, decorator) {
|
|
1849
|
+
return function(target, key) {
|
|
1850
|
+
decorator(target, key, paramIndex);
|
|
1851
|
+
};
|
|
1852
|
+
}
|
|
1853
|
+
__name(_ts_param9, "_ts_param");
|
|
1854
|
+
var BudgetExceededError = class extends Error {
|
|
1855
|
+
static {
|
|
1856
|
+
__name(this, "BudgetExceededError");
|
|
1857
|
+
}
|
|
1858
|
+
conversationId;
|
|
1859
|
+
spent;
|
|
1860
|
+
limit;
|
|
1861
|
+
constructor(conversationId, spent, limit) {
|
|
1862
|
+
super(`Budget exceeded${conversationId ? ` for "${conversationId}"` : ""}: $${spent.toFixed(4)} >= $${limit.toFixed(4)}.`), this.conversationId = conversationId, this.spent = spent, this.limit = limit;
|
|
1863
|
+
this.name = "BudgetExceededError";
|
|
1864
|
+
}
|
|
1865
|
+
};
|
|
1866
|
+
exports.BudgetGuard = class BudgetGuard {
|
|
1867
|
+
static {
|
|
1868
|
+
__name(this, "BudgetGuard");
|
|
1869
|
+
}
|
|
1870
|
+
usage;
|
|
1871
|
+
options;
|
|
1872
|
+
constructor(usage, options) {
|
|
1873
|
+
this.usage = usage;
|
|
1874
|
+
this.options = options;
|
|
1875
|
+
}
|
|
1876
|
+
beforeRun(ctx) {
|
|
1877
|
+
const limit = this.options.maxCostPerConversation;
|
|
1878
|
+
if (limit == null) {
|
|
1879
|
+
return;
|
|
1880
|
+
}
|
|
1881
|
+
const { cost } = this.usage.totals(ctx.options.conversationId);
|
|
1882
|
+
if (cost >= limit) {
|
|
1883
|
+
throw new BudgetExceededError(ctx.options.conversationId, cost, limit);
|
|
1884
|
+
}
|
|
1885
|
+
}
|
|
1886
|
+
};
|
|
1887
|
+
exports.BudgetGuard = _ts_decorate19([
|
|
1888
|
+
Guardrail(),
|
|
1889
|
+
common.Injectable(),
|
|
1890
|
+
_ts_param9(1, common.Inject(AI_MODULE_OPTIONS)),
|
|
1891
|
+
_ts_metadata15("design:type", Function),
|
|
1892
|
+
_ts_metadata15("design:paramtypes", [
|
|
1893
|
+
typeof exports.UsageTracker === "undefined" ? Object : exports.UsageTracker,
|
|
1894
|
+
typeof AiModuleOptions === "undefined" ? Object : AiModuleOptions
|
|
1895
|
+
])
|
|
1896
|
+
], exports.BudgetGuard);
|
|
1897
|
+
|
|
1898
|
+
// src/ratelimit/rate-limiter.interface.ts
|
|
1899
|
+
var RateLimitedError = class extends Error {
|
|
1900
|
+
static {
|
|
1901
|
+
__name(this, "RateLimitedError");
|
|
1902
|
+
}
|
|
1903
|
+
key;
|
|
1904
|
+
constructor(key) {
|
|
1905
|
+
super(`Rate limit exceeded for "${key}".`), this.key = key;
|
|
1906
|
+
this.name = "RateLimitedError";
|
|
1907
|
+
}
|
|
1908
|
+
};
|
|
1909
|
+
|
|
1910
|
+
// src/ratelimit/rate-limit.guardrail.ts
|
|
1911
|
+
function _ts_decorate20(decorators, target, key, desc) {
|
|
1912
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1913
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
1914
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
1915
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
1916
|
+
}
|
|
1917
|
+
__name(_ts_decorate20, "_ts_decorate");
|
|
1918
|
+
function _ts_metadata16(k, v) {
|
|
1919
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
1920
|
+
}
|
|
1921
|
+
__name(_ts_metadata16, "_ts_metadata");
|
|
1922
|
+
function _ts_param10(paramIndex, decorator) {
|
|
1923
|
+
return function(target, key) {
|
|
1924
|
+
decorator(target, key, paramIndex);
|
|
1925
|
+
};
|
|
1926
|
+
}
|
|
1927
|
+
__name(_ts_param10, "_ts_param");
|
|
1928
|
+
exports.RateLimitGuardrail = class RateLimitGuardrail {
|
|
1929
|
+
static {
|
|
1930
|
+
__name(this, "RateLimitGuardrail");
|
|
1931
|
+
}
|
|
1932
|
+
limiter;
|
|
1933
|
+
constructor(limiter) {
|
|
1934
|
+
this.limiter = limiter;
|
|
1935
|
+
}
|
|
1936
|
+
async beforeRun(ctx) {
|
|
1937
|
+
const key = ctx.options.conversationId ?? "global";
|
|
1938
|
+
const allowed = await this.limiter.consume(key);
|
|
1939
|
+
if (!allowed) {
|
|
1940
|
+
throw new RateLimitedError(key);
|
|
1941
|
+
}
|
|
1942
|
+
}
|
|
1943
|
+
};
|
|
1944
|
+
exports.RateLimitGuardrail = _ts_decorate20([
|
|
1945
|
+
Guardrail(),
|
|
1946
|
+
common.Injectable(),
|
|
1947
|
+
_ts_param10(0, common.Inject(RATE_LIMITER)),
|
|
1948
|
+
_ts_metadata16("design:type", Function),
|
|
1949
|
+
_ts_metadata16("design:paramtypes", [
|
|
1950
|
+
typeof RateLimiter === "undefined" ? Object : RateLimiter
|
|
1951
|
+
])
|
|
1952
|
+
], exports.RateLimitGuardrail);
|
|
1953
|
+
function _ts_decorate21(decorators, target, key, desc) {
|
|
1954
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1955
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
1956
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
1957
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
1958
|
+
}
|
|
1959
|
+
__name(_ts_decorate21, "_ts_decorate");
|
|
1960
|
+
function _ts_metadata17(k, v) {
|
|
1961
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
1962
|
+
}
|
|
1963
|
+
__name(_ts_metadata17, "_ts_metadata");
|
|
1964
|
+
function _ts_param11(paramIndex, decorator) {
|
|
1965
|
+
return function(target, key) {
|
|
1966
|
+
decorator(target, key, paramIndex);
|
|
1967
|
+
};
|
|
1968
|
+
}
|
|
1969
|
+
__name(_ts_param11, "_ts_param");
|
|
1970
|
+
exports.HeuristicReranker = class HeuristicReranker {
|
|
1971
|
+
static {
|
|
1972
|
+
__name(this, "HeuristicReranker");
|
|
1973
|
+
}
|
|
1974
|
+
options;
|
|
1975
|
+
constructor(options = {}) {
|
|
1976
|
+
this.options = options;
|
|
1977
|
+
}
|
|
1978
|
+
async rerank(query, results, topN) {
|
|
1979
|
+
const weight = this.options.overlapWeight ?? 0.5;
|
|
1980
|
+
const terms = tokenize(query);
|
|
1981
|
+
return results.map((result) => ({
|
|
1982
|
+
result,
|
|
1983
|
+
score: result.score + weight * overlap(terms, result.content)
|
|
1984
|
+
})).sort((a, b) => b.score - a.score).slice(0, topN).map(({ result, score }) => ({
|
|
1985
|
+
...result,
|
|
1986
|
+
score
|
|
1987
|
+
}));
|
|
1988
|
+
}
|
|
1989
|
+
};
|
|
1990
|
+
exports.HeuristicReranker = _ts_decorate21([
|
|
1991
|
+
common.Injectable(),
|
|
1992
|
+
_ts_param11(0, common.Optional()),
|
|
1993
|
+
_ts_metadata17("design:type", Function),
|
|
1994
|
+
_ts_metadata17("design:paramtypes", [
|
|
1995
|
+
typeof HeuristicRerankerOptions === "undefined" ? Object : HeuristicRerankerOptions
|
|
1996
|
+
])
|
|
1997
|
+
], exports.HeuristicReranker);
|
|
1998
|
+
function tokenize(text) {
|
|
1999
|
+
return new Set(text.toLowerCase().split(/[^a-z0-9]+/).filter((t) => t.length > 2));
|
|
2000
|
+
}
|
|
2001
|
+
__name(tokenize, "tokenize");
|
|
2002
|
+
function overlap(terms, content) {
|
|
2003
|
+
if (terms.size === 0) {
|
|
2004
|
+
return 0;
|
|
2005
|
+
}
|
|
2006
|
+
const contentTerms = tokenize(content);
|
|
2007
|
+
let hits = 0;
|
|
2008
|
+
for (const term of terms) {
|
|
2009
|
+
if (contentTerms.has(term)) {
|
|
2010
|
+
hits++;
|
|
2011
|
+
}
|
|
2012
|
+
}
|
|
2013
|
+
return hits / terms.size;
|
|
2014
|
+
}
|
|
2015
|
+
__name(overlap, "overlap");
|
|
2016
|
+
function _ts_decorate22(decorators, target, key, desc) {
|
|
2017
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
2018
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
2019
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
2020
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
2021
|
+
}
|
|
2022
|
+
__name(_ts_decorate22, "_ts_decorate");
|
|
2023
|
+
exports.EvalRunner = class EvalRunner {
|
|
2024
|
+
static {
|
|
2025
|
+
__name(this, "EvalRunner");
|
|
2026
|
+
}
|
|
2027
|
+
async run(agent, cases, options = {}) {
|
|
2028
|
+
const judge = options.judge ?? defaultJudge(options.passThreshold ?? 1);
|
|
2029
|
+
const results = [];
|
|
2030
|
+
for (const evalCase of cases) {
|
|
2031
|
+
const { text } = await agent.run(evalCase.input);
|
|
2032
|
+
const score = await judge({
|
|
2033
|
+
case: evalCase,
|
|
2034
|
+
output: text
|
|
2035
|
+
});
|
|
2036
|
+
results.push({
|
|
2037
|
+
name: evalCase.name ?? evalCase.input,
|
|
2038
|
+
input: evalCase.input,
|
|
2039
|
+
output: text,
|
|
2040
|
+
...score
|
|
2041
|
+
});
|
|
2042
|
+
}
|
|
2043
|
+
const averageScore = results.length ? results.reduce((sum, r) => sum + r.score, 0) / results.length : 0;
|
|
2044
|
+
const passRate = results.length ? results.filter((r) => r.passed).length / results.length : 0;
|
|
2045
|
+
return {
|
|
2046
|
+
results,
|
|
2047
|
+
averageScore,
|
|
2048
|
+
passRate
|
|
2049
|
+
};
|
|
2050
|
+
}
|
|
2051
|
+
};
|
|
2052
|
+
exports.EvalRunner = _ts_decorate22([
|
|
2053
|
+
common.Injectable()
|
|
2054
|
+
], exports.EvalRunner);
|
|
2055
|
+
function defaultJudge(threshold) {
|
|
2056
|
+
return ({ case: evalCase, output }) => {
|
|
2057
|
+
if (evalCase.expected == null) {
|
|
2058
|
+
return {
|
|
2059
|
+
score: 0,
|
|
2060
|
+
passed: false,
|
|
2061
|
+
reasoning: "no expected value or judge"
|
|
2062
|
+
};
|
|
2063
|
+
}
|
|
2064
|
+
const score = output.includes(evalCase.expected) ? 1 : 0;
|
|
2065
|
+
return {
|
|
2066
|
+
score,
|
|
2067
|
+
passed: score >= threshold
|
|
2068
|
+
};
|
|
2069
|
+
};
|
|
2070
|
+
}
|
|
2071
|
+
__name(defaultJudge, "defaultJudge");
|
|
2072
|
+
function createLlmJudge(ai, options = {}) {
|
|
2073
|
+
const scale = options.scale ?? 5;
|
|
2074
|
+
const passThreshold = options.passThreshold ?? 0.6;
|
|
2075
|
+
return async ({ case: evalCase, output }) => {
|
|
2076
|
+
const { object } = await ai.generateObject({
|
|
2077
|
+
model: options.model,
|
|
2078
|
+
schema: zod.z.object({
|
|
2079
|
+
score: zod.z.number(),
|
|
2080
|
+
reasoning: zod.z.string()
|
|
2081
|
+
}),
|
|
2082
|
+
prompt: `Rubric: ${evalCase.rubric ?? "Is the answer correct and helpful?"}
|
|
2083
|
+
Expected: ${evalCase.expected ?? "n/a"}
|
|
2084
|
+
Output: ${output}
|
|
2085
|
+
Give a score from 0 to ${scale} and a brief reasoning.`
|
|
2086
|
+
});
|
|
2087
|
+
const normalized = Math.max(0, Math.min(1, object.score / scale));
|
|
2088
|
+
return {
|
|
2089
|
+
score: normalized,
|
|
2090
|
+
passed: normalized >= passThreshold,
|
|
2091
|
+
reasoning: object.reasoning
|
|
2092
|
+
};
|
|
2093
|
+
};
|
|
2094
|
+
}
|
|
2095
|
+
__name(createLlmJudge, "createLlmJudge");
|
|
2096
|
+
|
|
2097
|
+
// src/ai.module.ts
|
|
2098
|
+
function _ts_decorate23(decorators, target, key, desc) {
|
|
2099
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
2100
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
2101
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
2102
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
2103
|
+
}
|
|
2104
|
+
__name(_ts_decorate23, "_ts_decorate");
|
|
2105
|
+
var AI_INITIALIZER = /* @__PURE__ */ Symbol("AI_INITIALIZER");
|
|
2106
|
+
exports.AiModule = class _AiModule {
|
|
2107
|
+
static {
|
|
2108
|
+
__name(this, "AiModule");
|
|
2109
|
+
}
|
|
2110
|
+
/** Configure the module with static options. */
|
|
2111
|
+
static forRoot(options = {}) {
|
|
2112
|
+
return _AiModule.build({
|
|
2113
|
+
provide: AI_MODULE_OPTIONS,
|
|
2114
|
+
useValue: options
|
|
2115
|
+
}, options);
|
|
2116
|
+
}
|
|
2117
|
+
/** Configure the module asynchronously (e.g. from `ConfigService`). */
|
|
2118
|
+
static forRootAsync(options) {
|
|
2119
|
+
return _AiModule.build({
|
|
2120
|
+
provide: AI_MODULE_OPTIONS,
|
|
2121
|
+
useFactory: options.useFactory,
|
|
2122
|
+
inject: options.inject ?? []
|
|
2123
|
+
}, options, options.imports);
|
|
2124
|
+
}
|
|
2125
|
+
/**
|
|
2126
|
+
* Convenience registration of agents / tools / guardrails so they don't have
|
|
2127
|
+
* to be added to a consuming module's own `providers` array, plus feature
|
|
2128
|
+
* prompts. Discovery still finds providers globally regardless of where they
|
|
2129
|
+
* are registered.
|
|
2130
|
+
*/
|
|
2131
|
+
static forFeature(feature = {}) {
|
|
2132
|
+
const providers = [
|
|
2133
|
+
...feature.agents ?? [],
|
|
2134
|
+
...feature.tools ?? [],
|
|
2135
|
+
...feature.guardrails ?? []
|
|
2136
|
+
];
|
|
2137
|
+
if (feature.prompts?.length) {
|
|
2138
|
+
providers.push({
|
|
2139
|
+
provide: /* @__PURE__ */ Symbol("AI_FEATURE_PROMPTS"),
|
|
2140
|
+
useFactory: /* @__PURE__ */ __name((registry) => {
|
|
2141
|
+
registry.registerAll(feature.prompts);
|
|
2142
|
+
return true;
|
|
2143
|
+
}, "useFactory"),
|
|
2144
|
+
inject: [
|
|
2145
|
+
exports.PromptRegistry
|
|
2146
|
+
]
|
|
2147
|
+
});
|
|
2148
|
+
}
|
|
2149
|
+
return {
|
|
2150
|
+
module: _AiModule,
|
|
2151
|
+
providers,
|
|
2152
|
+
exports: providers
|
|
2153
|
+
};
|
|
2154
|
+
}
|
|
2155
|
+
static build(optionsProvider, options, extraImports = []) {
|
|
2156
|
+
return {
|
|
2157
|
+
module: _AiModule,
|
|
2158
|
+
imports: [
|
|
2159
|
+
core.DiscoveryModule,
|
|
2160
|
+
...extraImports ?? []
|
|
2161
|
+
],
|
|
2162
|
+
providers: [
|
|
2163
|
+
optionsProvider,
|
|
2164
|
+
_AiModule.storeProvider(options.conversationStore),
|
|
2165
|
+
_AiModule.vectorStoreProvider(options.vectorStore),
|
|
2166
|
+
_AiModule.eventEmitterProvider(),
|
|
2167
|
+
..._AiModule.tokenProvider(AI_CACHE, options.cache),
|
|
2168
|
+
..._AiModule.tokenProvider(APPROVAL_GATE, options.approvalGate),
|
|
2169
|
+
..._AiModule.tokenProvider(RATE_LIMITER, options.rateLimiter),
|
|
2170
|
+
..._AiModule.guardrailClasses(options.guardrails),
|
|
2171
|
+
...options.maxCostPerConversation != null ? [
|
|
2172
|
+
exports.BudgetGuard
|
|
2173
|
+
] : [],
|
|
2174
|
+
...options.rateLimiter ? [
|
|
2175
|
+
exports.RateLimitGuardrail
|
|
2176
|
+
] : [],
|
|
2177
|
+
..._AiModule.coreProviders(),
|
|
2178
|
+
_AiModule.initializerProvider()
|
|
2179
|
+
],
|
|
2180
|
+
exports: _AiModule.exportedTokens()
|
|
2181
|
+
};
|
|
2182
|
+
}
|
|
2183
|
+
static coreProviders() {
|
|
2184
|
+
return [
|
|
2185
|
+
exports.ProviderRegistry,
|
|
2186
|
+
exports.ToolRegistry,
|
|
2187
|
+
exports.AgentExecutorService,
|
|
2188
|
+
exports.AgentRegistry,
|
|
2189
|
+
exports.AiService,
|
|
2190
|
+
exports.EmbeddingsService,
|
|
2191
|
+
exports.ImageService,
|
|
2192
|
+
exports.SpeechService,
|
|
2193
|
+
exports.TranscriptionService,
|
|
2194
|
+
exports.RagService,
|
|
2195
|
+
exports.PromptRegistry,
|
|
2196
|
+
exports.AiEventEmitter,
|
|
2197
|
+
exports.GuardrailRegistry,
|
|
2198
|
+
exports.McpService,
|
|
2199
|
+
exports.UsageTracker,
|
|
2200
|
+
exports.SemanticMemory,
|
|
2201
|
+
exports.EvalRunner,
|
|
2202
|
+
{
|
|
2203
|
+
provide: RERANKER,
|
|
2204
|
+
useFactory: /* @__PURE__ */ __name(() => new exports.HeuristicReranker(), "useFactory")
|
|
2205
|
+
}
|
|
2206
|
+
];
|
|
2207
|
+
}
|
|
2208
|
+
/**
|
|
2209
|
+
* Registers an optional provider (class / factory / value / useClass shape)
|
|
2210
|
+
* under `token`, or nothing when not configured.
|
|
2211
|
+
*/
|
|
2212
|
+
static tokenProvider(token, config) {
|
|
2213
|
+
if (!config) {
|
|
2214
|
+
return [];
|
|
2215
|
+
}
|
|
2216
|
+
if (typeof config === "function") {
|
|
2217
|
+
return [
|
|
2218
|
+
{
|
|
2219
|
+
provide: token,
|
|
2220
|
+
useClass: config
|
|
2221
|
+
}
|
|
2222
|
+
];
|
|
2223
|
+
}
|
|
2224
|
+
return [
|
|
2225
|
+
{
|
|
2226
|
+
provide: token,
|
|
2227
|
+
...config
|
|
2228
|
+
}
|
|
2229
|
+
];
|
|
2230
|
+
}
|
|
2231
|
+
static exportedTokens() {
|
|
2232
|
+
return [
|
|
2233
|
+
exports.ProviderRegistry,
|
|
2234
|
+
exports.ToolRegistry,
|
|
2235
|
+
exports.AgentExecutorService,
|
|
2236
|
+
exports.AgentRegistry,
|
|
2237
|
+
exports.AiService,
|
|
2238
|
+
exports.EmbeddingsService,
|
|
2239
|
+
exports.ImageService,
|
|
2240
|
+
exports.SpeechService,
|
|
2241
|
+
exports.TranscriptionService,
|
|
2242
|
+
exports.RagService,
|
|
2243
|
+
exports.PromptRegistry,
|
|
2244
|
+
exports.AiEventEmitter,
|
|
2245
|
+
exports.GuardrailRegistry,
|
|
2246
|
+
exports.McpService,
|
|
2247
|
+
exports.UsageTracker,
|
|
2248
|
+
exports.SemanticMemory,
|
|
2249
|
+
exports.EvalRunner,
|
|
2250
|
+
RERANKER,
|
|
2251
|
+
CONVERSATION_STORE,
|
|
2252
|
+
VECTOR_STORE,
|
|
2253
|
+
AI_MODULE_OPTIONS
|
|
2254
|
+
];
|
|
2255
|
+
}
|
|
2256
|
+
static guardrailClasses(guardrails) {
|
|
2257
|
+
return guardrails ?? [];
|
|
2258
|
+
}
|
|
2259
|
+
/** Seeds prompts (and future startup wiring) once dependencies exist. */
|
|
2260
|
+
static initializerProvider() {
|
|
2261
|
+
return {
|
|
2262
|
+
provide: AI_INITIALIZER,
|
|
2263
|
+
useFactory: /* @__PURE__ */ __name((registry, opts) => {
|
|
2264
|
+
if (opts.prompts?.length) {
|
|
2265
|
+
registry.registerAll(opts.prompts);
|
|
2266
|
+
}
|
|
2267
|
+
return true;
|
|
2268
|
+
}, "useFactory"),
|
|
2269
|
+
inject: [
|
|
2270
|
+
exports.PromptRegistry,
|
|
2271
|
+
AI_MODULE_OPTIONS
|
|
2272
|
+
]
|
|
2273
|
+
};
|
|
2274
|
+
}
|
|
2275
|
+
/**
|
|
2276
|
+
* Optionally resolves `EventEmitter2` from `@nestjs/event-emitter` if the
|
|
2277
|
+
* package is installed and its module is imported; otherwise `undefined`.
|
|
2278
|
+
*/
|
|
2279
|
+
static eventEmitterProvider() {
|
|
2280
|
+
return {
|
|
2281
|
+
provide: EVENT_EMITTER,
|
|
2282
|
+
useFactory: /* @__PURE__ */ __name(async (moduleRef) => {
|
|
2283
|
+
try {
|
|
2284
|
+
const mod = await import('@nestjs/event-emitter');
|
|
2285
|
+
return moduleRef.get(mod.EventEmitter2, {
|
|
2286
|
+
strict: false
|
|
2287
|
+
});
|
|
2288
|
+
} catch {
|
|
2289
|
+
return void 0;
|
|
2290
|
+
}
|
|
2291
|
+
}, "useFactory"),
|
|
2292
|
+
inject: [
|
|
2293
|
+
core.ModuleRef
|
|
2294
|
+
]
|
|
2295
|
+
};
|
|
2296
|
+
}
|
|
2297
|
+
static storeProvider(store) {
|
|
2298
|
+
if (!store) {
|
|
2299
|
+
return {
|
|
2300
|
+
provide: CONVERSATION_STORE,
|
|
2301
|
+
useClass: exports.InMemoryConversationStore
|
|
2302
|
+
};
|
|
2303
|
+
}
|
|
2304
|
+
if (typeof store === "function") {
|
|
2305
|
+
return {
|
|
2306
|
+
provide: CONVERSATION_STORE,
|
|
2307
|
+
useClass: store
|
|
2308
|
+
};
|
|
2309
|
+
}
|
|
2310
|
+
return {
|
|
2311
|
+
provide: CONVERSATION_STORE,
|
|
2312
|
+
...store
|
|
2313
|
+
};
|
|
2314
|
+
}
|
|
2315
|
+
static vectorStoreProvider(store) {
|
|
2316
|
+
if (!store) {
|
|
2317
|
+
return {
|
|
2318
|
+
provide: VECTOR_STORE,
|
|
2319
|
+
useClass: exports.InMemoryVectorStore
|
|
2320
|
+
};
|
|
2321
|
+
}
|
|
2322
|
+
if (typeof store === "function") {
|
|
2323
|
+
return {
|
|
2324
|
+
provide: VECTOR_STORE,
|
|
2325
|
+
useClass: store
|
|
2326
|
+
};
|
|
2327
|
+
}
|
|
2328
|
+
return {
|
|
2329
|
+
provide: VECTOR_STORE,
|
|
2330
|
+
...store
|
|
2331
|
+
};
|
|
2332
|
+
}
|
|
2333
|
+
};
|
|
2334
|
+
exports.AiModule = _ts_decorate23([
|
|
2335
|
+
common.Global(),
|
|
2336
|
+
common.Module({})
|
|
2337
|
+
], exports.AiModule);
|
|
2338
|
+
function Tool(options) {
|
|
2339
|
+
return (target, propertyKey, descriptor) => {
|
|
2340
|
+
const metadata = {
|
|
2341
|
+
...options,
|
|
2342
|
+
methodName: String(propertyKey)
|
|
2343
|
+
};
|
|
2344
|
+
Reflect.defineMetadata(TOOL_METADATA, metadata, descriptor.value);
|
|
2345
|
+
return descriptor;
|
|
2346
|
+
};
|
|
2347
|
+
}
|
|
2348
|
+
__name(Tool, "Tool");
|
|
2349
|
+
function Agent(options = {}) {
|
|
2350
|
+
return (target) => {
|
|
2351
|
+
Reflect.defineMetadata(AGENT_METADATA, options, target);
|
|
2352
|
+
common.Injectable()(target);
|
|
2353
|
+
};
|
|
2354
|
+
}
|
|
2355
|
+
__name(Agent, "Agent");
|
|
2356
|
+
function _ts_decorate24(decorators, target, key, desc) {
|
|
2357
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
2358
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
2359
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
2360
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
2361
|
+
}
|
|
2362
|
+
__name(_ts_decorate24, "_ts_decorate");
|
|
2363
|
+
function _ts_metadata18(k, v) {
|
|
2364
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
2365
|
+
}
|
|
2366
|
+
__name(_ts_metadata18, "_ts_metadata");
|
|
2367
|
+
var AiAgent = class {
|
|
2368
|
+
static {
|
|
2369
|
+
__name(this, "AiAgent");
|
|
2370
|
+
}
|
|
2371
|
+
executor;
|
|
2372
|
+
/** Runs the agent to completion. */
|
|
2373
|
+
run(input, opts) {
|
|
2374
|
+
return this.executor.run(this, input, opts);
|
|
2375
|
+
}
|
|
2376
|
+
/** Streams the agent's response (returns the raw Vercel stream result). */
|
|
2377
|
+
stream(input, opts) {
|
|
2378
|
+
return this.executor.stream(this, input, opts);
|
|
2379
|
+
}
|
|
2380
|
+
};
|
|
2381
|
+
_ts_decorate24([
|
|
2382
|
+
common.Inject(exports.AgentExecutorService),
|
|
2383
|
+
_ts_metadata18("design:type", typeof exports.AgentExecutorService === "undefined" ? Object : exports.AgentExecutorService)
|
|
2384
|
+
], AiAgent.prototype, "executor", void 0);
|
|
2385
|
+
function createRetrievalTool(rag, options = {}) {
|
|
2386
|
+
return ai.tool({
|
|
2387
|
+
description: options.description ?? "Search the knowledge base for information relevant to the query.",
|
|
2388
|
+
inputSchema: zod.z.object({
|
|
2389
|
+
query: zod.z.string().describe("The search query")
|
|
2390
|
+
}),
|
|
2391
|
+
execute: /* @__PURE__ */ __name(async ({ query }) => {
|
|
2392
|
+
const results = await rag.retrieve(query, {
|
|
2393
|
+
topK: options.topK,
|
|
2394
|
+
model: options.model,
|
|
2395
|
+
filter: options.filter
|
|
2396
|
+
});
|
|
2397
|
+
if (results.length === 0) {
|
|
2398
|
+
return "No relevant information found.";
|
|
2399
|
+
}
|
|
2400
|
+
return results.map((r, i) => `[${i + 1}] ${r.content}`).join("\n\n");
|
|
2401
|
+
}, "execute")
|
|
2402
|
+
});
|
|
2403
|
+
}
|
|
2404
|
+
__name(createRetrievalTool, "createRetrievalTool");
|
|
2405
|
+
|
|
2406
|
+
// src/memory/adapters/prisma/prisma-conversation.store.ts
|
|
2407
|
+
var PrismaConversationStore = class {
|
|
2408
|
+
static {
|
|
2409
|
+
__name(this, "PrismaConversationStore");
|
|
2410
|
+
}
|
|
2411
|
+
delegate;
|
|
2412
|
+
constructor(delegate) {
|
|
2413
|
+
this.delegate = delegate;
|
|
2414
|
+
}
|
|
2415
|
+
async load(conversationId) {
|
|
2416
|
+
const rows = await this.delegate.findMany({
|
|
2417
|
+
where: {
|
|
2418
|
+
conversationId
|
|
2419
|
+
},
|
|
2420
|
+
orderBy: {
|
|
2421
|
+
position: "asc"
|
|
2422
|
+
}
|
|
2423
|
+
});
|
|
2424
|
+
return rows.map((row) => ({
|
|
2425
|
+
role: row.role,
|
|
2426
|
+
content: row.content
|
|
2427
|
+
}));
|
|
2428
|
+
}
|
|
2429
|
+
async append(conversationId, messages) {
|
|
2430
|
+
if (messages.length === 0) {
|
|
2431
|
+
return;
|
|
2432
|
+
}
|
|
2433
|
+
const base = await this.delegate.count({
|
|
2434
|
+
where: {
|
|
2435
|
+
conversationId
|
|
2436
|
+
}
|
|
2437
|
+
});
|
|
2438
|
+
for (let index = 0; index < messages.length; index++) {
|
|
2439
|
+
const message = messages[index];
|
|
2440
|
+
await this.delegate.create({
|
|
2441
|
+
data: {
|
|
2442
|
+
conversationId,
|
|
2443
|
+
role: message.role,
|
|
2444
|
+
content: message.content,
|
|
2445
|
+
position: base + index
|
|
2446
|
+
}
|
|
2447
|
+
});
|
|
2448
|
+
}
|
|
2449
|
+
}
|
|
2450
|
+
async clear(conversationId) {
|
|
2451
|
+
await this.delegate.deleteMany({
|
|
2452
|
+
where: {
|
|
2453
|
+
conversationId
|
|
2454
|
+
}
|
|
2455
|
+
});
|
|
2456
|
+
}
|
|
2457
|
+
};
|
|
2458
|
+
function _ts_decorate25(decorators, target, key, desc) {
|
|
2459
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
2460
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
2461
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
2462
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
2463
|
+
}
|
|
2464
|
+
__name(_ts_decorate25, "_ts_decorate");
|
|
2465
|
+
exports.InMemoryAiCache = class InMemoryAiCache {
|
|
2466
|
+
static {
|
|
2467
|
+
__name(this, "InMemoryAiCache");
|
|
2468
|
+
}
|
|
2469
|
+
store = /* @__PURE__ */ new Map();
|
|
2470
|
+
async get(key) {
|
|
2471
|
+
const entry = this.store.get(key);
|
|
2472
|
+
if (!entry) {
|
|
2473
|
+
return void 0;
|
|
2474
|
+
}
|
|
2475
|
+
if (entry.expiresAt !== null && entry.expiresAt <= Date.now()) {
|
|
2476
|
+
this.store.delete(key);
|
|
2477
|
+
return void 0;
|
|
2478
|
+
}
|
|
2479
|
+
return entry.value;
|
|
2480
|
+
}
|
|
2481
|
+
async set(key, value, ttlMs) {
|
|
2482
|
+
this.store.set(key, {
|
|
2483
|
+
value,
|
|
2484
|
+
expiresAt: ttlMs != null ? Date.now() + ttlMs : null
|
|
2485
|
+
});
|
|
2486
|
+
}
|
|
2487
|
+
};
|
|
2488
|
+
exports.InMemoryAiCache = _ts_decorate25([
|
|
2489
|
+
common.Injectable()
|
|
2490
|
+
], exports.InMemoryAiCache);
|
|
2491
|
+
function _ts_decorate26(decorators, target, key, desc) {
|
|
2492
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
2493
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
2494
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
2495
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
2496
|
+
}
|
|
2497
|
+
__name(_ts_decorate26, "_ts_decorate");
|
|
2498
|
+
exports.AutoApproveGate = class AutoApproveGate {
|
|
2499
|
+
static {
|
|
2500
|
+
__name(this, "AutoApproveGate");
|
|
2501
|
+
}
|
|
2502
|
+
async requestApproval(_context) {
|
|
2503
|
+
return true;
|
|
2504
|
+
}
|
|
2505
|
+
};
|
|
2506
|
+
exports.AutoApproveGate = _ts_decorate26([
|
|
2507
|
+
common.Injectable()
|
|
2508
|
+
], exports.AutoApproveGate);
|
|
2509
|
+
exports.DenyApproveGate = class DenyApproveGate {
|
|
2510
|
+
static {
|
|
2511
|
+
__name(this, "DenyApproveGate");
|
|
2512
|
+
}
|
|
2513
|
+
async requestApproval(_context) {
|
|
2514
|
+
return false;
|
|
2515
|
+
}
|
|
2516
|
+
};
|
|
2517
|
+
exports.DenyApproveGate = _ts_decorate26([
|
|
2518
|
+
common.Injectable()
|
|
2519
|
+
], exports.DenyApproveGate);
|
|
2520
|
+
|
|
2521
|
+
// src/http/stream-response.ts
|
|
2522
|
+
function pipeAgentStream(result, res, options = {}) {
|
|
2523
|
+
const protocol = options.protocol ?? "ui";
|
|
2524
|
+
if (protocol === "text") {
|
|
2525
|
+
if (typeof result.pipeTextStreamToResponse === "function") {
|
|
2526
|
+
result.pipeTextStreamToResponse(res);
|
|
2527
|
+
return;
|
|
2528
|
+
}
|
|
2529
|
+
} else if (typeof result.pipeUIMessageStreamToResponse === "function") {
|
|
2530
|
+
result.pipeUIMessageStreamToResponse(res);
|
|
2531
|
+
return;
|
|
2532
|
+
}
|
|
2533
|
+
throw new Error(`The stream result does not support the "${protocol}" protocol.`);
|
|
2534
|
+
}
|
|
2535
|
+
__name(pipeAgentStream, "pipeAgentStream");
|
|
2536
|
+
function _ts_decorate27(decorators, target, key, desc) {
|
|
2537
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
2538
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
2539
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
2540
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
2541
|
+
}
|
|
2542
|
+
__name(_ts_decorate27, "_ts_decorate");
|
|
2543
|
+
function _ts_metadata19(k, v) {
|
|
2544
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
2545
|
+
}
|
|
2546
|
+
__name(_ts_metadata19, "_ts_metadata");
|
|
2547
|
+
exports.AgentStreamInterceptor = class AgentStreamInterceptor {
|
|
2548
|
+
static {
|
|
2549
|
+
__name(this, "AgentStreamInterceptor");
|
|
2550
|
+
}
|
|
2551
|
+
options;
|
|
2552
|
+
constructor(options = {}) {
|
|
2553
|
+
this.options = options;
|
|
2554
|
+
}
|
|
2555
|
+
intercept(context, next) {
|
|
2556
|
+
const res = context.switchToHttp().getResponse();
|
|
2557
|
+
return next.handle().pipe(rxjs.mergeMap((result) => {
|
|
2558
|
+
pipeAgentStream(result, res, this.options);
|
|
2559
|
+
return rxjs.EMPTY;
|
|
2560
|
+
}));
|
|
2561
|
+
}
|
|
2562
|
+
};
|
|
2563
|
+
exports.AgentStreamInterceptor = _ts_decorate27([
|
|
2564
|
+
common.Injectable(),
|
|
2565
|
+
_ts_metadata19("design:type", Function),
|
|
2566
|
+
_ts_metadata19("design:paramtypes", [
|
|
2567
|
+
typeof PipeAgentStreamOptions === "undefined" ? Object : PipeAgentStreamOptions
|
|
2568
|
+
])
|
|
2569
|
+
], exports.AgentStreamInterceptor);
|
|
2570
|
+
function _ts_decorate28(decorators, target, key, desc) {
|
|
2571
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
2572
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
2573
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
2574
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
2575
|
+
}
|
|
2576
|
+
__name(_ts_decorate28, "_ts_decorate");
|
|
2577
|
+
function _ts_metadata20(k, v) {
|
|
2578
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
2579
|
+
}
|
|
2580
|
+
__name(_ts_metadata20, "_ts_metadata");
|
|
2581
|
+
function _ts_param12(paramIndex, decorator) {
|
|
2582
|
+
return function(target, key) {
|
|
2583
|
+
decorator(target, key, paramIndex);
|
|
2584
|
+
};
|
|
2585
|
+
}
|
|
2586
|
+
__name(_ts_param12, "_ts_param");
|
|
2587
|
+
var AGENT_JOB_NAME = "agent-run";
|
|
2588
|
+
exports.AgentQueueService = class AgentQueueService {
|
|
2589
|
+
static {
|
|
2590
|
+
__name(this, "AgentQueueService");
|
|
2591
|
+
}
|
|
2592
|
+
queue;
|
|
2593
|
+
constructor(queue) {
|
|
2594
|
+
this.queue = queue;
|
|
2595
|
+
}
|
|
2596
|
+
/** Enqueues an agent run and returns the created job id. */
|
|
2597
|
+
async enqueue(data, jobOptions) {
|
|
2598
|
+
const job = await this.queue.add(AGENT_JOB_NAME, data, jobOptions);
|
|
2599
|
+
return job.id;
|
|
2600
|
+
}
|
|
2601
|
+
};
|
|
2602
|
+
exports.AgentQueueService = _ts_decorate28([
|
|
2603
|
+
common.Injectable(),
|
|
2604
|
+
_ts_param12(0, common.Inject(AGENT_QUEUE)),
|
|
2605
|
+
_ts_metadata20("design:type", Function),
|
|
2606
|
+
_ts_metadata20("design:paramtypes", [
|
|
2607
|
+
typeof QueueLike === "undefined" ? Object : QueueLike
|
|
2608
|
+
])
|
|
2609
|
+
], exports.AgentQueueService);
|
|
2610
|
+
function _ts_decorate29(decorators, target, key, desc) {
|
|
2611
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
2612
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
2613
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
2614
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
2615
|
+
}
|
|
2616
|
+
__name(_ts_decorate29, "_ts_decorate");
|
|
2617
|
+
function _ts_metadata21(k, v) {
|
|
2618
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
2619
|
+
}
|
|
2620
|
+
__name(_ts_metadata21, "_ts_metadata");
|
|
2621
|
+
exports.AgentJobProcessor = class AgentJobProcessor {
|
|
2622
|
+
static {
|
|
2623
|
+
__name(this, "AgentJobProcessor");
|
|
2624
|
+
}
|
|
2625
|
+
agents;
|
|
2626
|
+
constructor(agents) {
|
|
2627
|
+
this.agents = agents;
|
|
2628
|
+
}
|
|
2629
|
+
async run(data) {
|
|
2630
|
+
const agent = this.agents.get(data.agent);
|
|
2631
|
+
if (!agent) {
|
|
2632
|
+
throw new Error(`Cannot process job: unknown agent "${data.agent}". Is it registered?`);
|
|
2633
|
+
}
|
|
2634
|
+
return agent.run(data.input, data.options);
|
|
2635
|
+
}
|
|
2636
|
+
};
|
|
2637
|
+
exports.AgentJobProcessor = _ts_decorate29([
|
|
2638
|
+
common.Injectable(),
|
|
2639
|
+
_ts_metadata21("design:type", Function),
|
|
2640
|
+
_ts_metadata21("design:paramtypes", [
|
|
2641
|
+
typeof exports.AgentRegistry === "undefined" ? Object : exports.AgentRegistry
|
|
2642
|
+
])
|
|
2643
|
+
], exports.AgentJobProcessor);
|
|
2644
|
+
|
|
2645
|
+
// src/jobs/agent-jobs.module.ts
|
|
2646
|
+
function _ts_decorate30(decorators, target, key, desc) {
|
|
2647
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
2648
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
2649
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
2650
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
2651
|
+
}
|
|
2652
|
+
__name(_ts_decorate30, "_ts_decorate");
|
|
2653
|
+
function _ts_metadata22(k, v) {
|
|
2654
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
2655
|
+
}
|
|
2656
|
+
__name(_ts_metadata22, "_ts_metadata");
|
|
2657
|
+
function _ts_param13(paramIndex, decorator) {
|
|
2658
|
+
return function(target, key) {
|
|
2659
|
+
decorator(target, key, paramIndex);
|
|
2660
|
+
};
|
|
2661
|
+
}
|
|
2662
|
+
__name(_ts_param13, "_ts_param");
|
|
2663
|
+
var AGENT_JOBS_OPTIONS = /* @__PURE__ */ Symbol("AGENT_JOBS_OPTIONS");
|
|
2664
|
+
var DEFAULT_QUEUE = "ai-agent-runs";
|
|
2665
|
+
async function loadBullMq() {
|
|
2666
|
+
const specifier = "bullmq";
|
|
2667
|
+
return import(specifier);
|
|
2668
|
+
}
|
|
2669
|
+
__name(loadBullMq, "loadBullMq");
|
|
2670
|
+
var AgentWorkerManager = class AgentWorkerManager2 {
|
|
2671
|
+
static {
|
|
2672
|
+
__name(this, "AgentWorkerManager");
|
|
2673
|
+
}
|
|
2674
|
+
options;
|
|
2675
|
+
processor;
|
|
2676
|
+
worker;
|
|
2677
|
+
constructor(options, processor) {
|
|
2678
|
+
this.options = options;
|
|
2679
|
+
this.processor = processor;
|
|
2680
|
+
}
|
|
2681
|
+
async onModuleInit() {
|
|
2682
|
+
if (this.options.runWorker === false) {
|
|
2683
|
+
return;
|
|
2684
|
+
}
|
|
2685
|
+
const { Worker } = await loadBullMq();
|
|
2686
|
+
this.worker = new Worker(this.options.queueName ?? DEFAULT_QUEUE, async (job) => {
|
|
2687
|
+
if (job.name === AGENT_JOB_NAME) {
|
|
2688
|
+
return this.processor.run(job.data);
|
|
2689
|
+
}
|
|
2690
|
+
return void 0;
|
|
2691
|
+
}, {
|
|
2692
|
+
connection: this.options.connection
|
|
2693
|
+
});
|
|
2694
|
+
}
|
|
2695
|
+
async onModuleDestroy() {
|
|
2696
|
+
await this.worker?.close();
|
|
2697
|
+
}
|
|
2698
|
+
};
|
|
2699
|
+
AgentWorkerManager = _ts_decorate30([
|
|
2700
|
+
common.Injectable(),
|
|
2701
|
+
_ts_param13(0, common.Inject(AGENT_JOBS_OPTIONS)),
|
|
2702
|
+
_ts_metadata22("design:type", Function),
|
|
2703
|
+
_ts_metadata22("design:paramtypes", [
|
|
2704
|
+
typeof AgentJobsOptions === "undefined" ? Object : AgentJobsOptions,
|
|
2705
|
+
typeof exports.AgentJobProcessor === "undefined" ? Object : exports.AgentJobProcessor
|
|
2706
|
+
])
|
|
2707
|
+
], AgentWorkerManager);
|
|
2708
|
+
exports.AgentJobsModule = class _AgentJobsModule {
|
|
2709
|
+
static {
|
|
2710
|
+
__name(this, "AgentJobsModule");
|
|
2711
|
+
}
|
|
2712
|
+
static forRoot(options) {
|
|
2713
|
+
return {
|
|
2714
|
+
module: _AgentJobsModule,
|
|
2715
|
+
providers: [
|
|
2716
|
+
{
|
|
2717
|
+
provide: AGENT_JOBS_OPTIONS,
|
|
2718
|
+
useValue: options
|
|
2719
|
+
},
|
|
2720
|
+
{
|
|
2721
|
+
provide: AGENT_QUEUE,
|
|
2722
|
+
useFactory: /* @__PURE__ */ __name(async () => {
|
|
2723
|
+
const { Queue } = await loadBullMq();
|
|
2724
|
+
return new Queue(options.queueName ?? DEFAULT_QUEUE, {
|
|
2725
|
+
connection: options.connection
|
|
2726
|
+
});
|
|
2727
|
+
}, "useFactory")
|
|
2728
|
+
},
|
|
2729
|
+
exports.AgentQueueService,
|
|
2730
|
+
exports.AgentJobProcessor,
|
|
2731
|
+
AgentWorkerManager
|
|
2732
|
+
],
|
|
2733
|
+
exports: [
|
|
2734
|
+
exports.AgentQueueService,
|
|
2735
|
+
exports.AgentJobProcessor
|
|
2736
|
+
]
|
|
2737
|
+
};
|
|
2738
|
+
}
|
|
2739
|
+
};
|
|
2740
|
+
exports.AgentJobsModule = _ts_decorate30([
|
|
2741
|
+
common.Module({})
|
|
2742
|
+
], exports.AgentJobsModule);
|
|
2743
|
+
|
|
2744
|
+
// src/rag/adapters/pgvector/pgvector-store.ts
|
|
2745
|
+
var PgVectorStore = class {
|
|
2746
|
+
static {
|
|
2747
|
+
__name(this, "PgVectorStore");
|
|
2748
|
+
}
|
|
2749
|
+
pool;
|
|
2750
|
+
table;
|
|
2751
|
+
constructor(pool, options = {}) {
|
|
2752
|
+
this.pool = pool;
|
|
2753
|
+
this.table = options.table ?? "ai_documents";
|
|
2754
|
+
}
|
|
2755
|
+
async upsert(documents) {
|
|
2756
|
+
for (const doc of documents) {
|
|
2757
|
+
if (!doc.embedding) {
|
|
2758
|
+
throw new Error(`Document "${doc.id}" has no embedding. PgVectorStore requires precomputed embeddings (use RagService.ingest).`);
|
|
2759
|
+
}
|
|
2760
|
+
await this.pool.query(`INSERT INTO ${this.table} (id, content, embedding, metadata)
|
|
2761
|
+
VALUES ($1, $2, $3, $4)
|
|
2762
|
+
ON CONFLICT (id) DO UPDATE
|
|
2763
|
+
SET content = EXCLUDED.content,
|
|
2764
|
+
embedding = EXCLUDED.embedding,
|
|
2765
|
+
metadata = EXCLUDED.metadata`, [
|
|
2766
|
+
doc.id,
|
|
2767
|
+
doc.content,
|
|
2768
|
+
toVectorLiteral(doc.embedding),
|
|
2769
|
+
doc.metadata ? JSON.stringify(doc.metadata) : null
|
|
2770
|
+
]);
|
|
2771
|
+
}
|
|
2772
|
+
}
|
|
2773
|
+
async query(embedding, options = {}) {
|
|
2774
|
+
const topK = options.topK ?? 4;
|
|
2775
|
+
const vector = toVectorLiteral(embedding);
|
|
2776
|
+
const params = [
|
|
2777
|
+
vector
|
|
2778
|
+
];
|
|
2779
|
+
let where = "";
|
|
2780
|
+
if (options.filter) {
|
|
2781
|
+
params.push(JSON.stringify(options.filter));
|
|
2782
|
+
where = `WHERE metadata @> $${params.length}`;
|
|
2783
|
+
}
|
|
2784
|
+
params.push(topK);
|
|
2785
|
+
const limitParam = `$${params.length}`;
|
|
2786
|
+
const { rows } = await this.pool.query(`SELECT id, content, metadata, 1 - (embedding <=> $1) AS score
|
|
2787
|
+
FROM ${this.table}
|
|
2788
|
+
${where}
|
|
2789
|
+
ORDER BY embedding <=> $1
|
|
2790
|
+
LIMIT ${limitParam}`, params);
|
|
2791
|
+
return rows.map((row) => ({
|
|
2792
|
+
id: row.id,
|
|
2793
|
+
content: row.content,
|
|
2794
|
+
score: Number(row.score),
|
|
2795
|
+
metadata: row.metadata ?? void 0
|
|
2796
|
+
}));
|
|
2797
|
+
}
|
|
2798
|
+
async delete(ids) {
|
|
2799
|
+
if (ids.length === 0) {
|
|
2800
|
+
return;
|
|
2801
|
+
}
|
|
2802
|
+
await this.pool.query(`DELETE FROM ${this.table} WHERE id = ANY($1)`, [
|
|
2803
|
+
ids
|
|
2804
|
+
]);
|
|
2805
|
+
}
|
|
2806
|
+
async clear() {
|
|
2807
|
+
await this.pool.query(`DELETE FROM ${this.table}`);
|
|
2808
|
+
}
|
|
2809
|
+
};
|
|
2810
|
+
function toVectorLiteral(embedding) {
|
|
2811
|
+
return `[${embedding.join(",")}]`;
|
|
2812
|
+
}
|
|
2813
|
+
__name(toVectorLiteral, "toVectorLiteral");
|
|
2814
|
+
|
|
2815
|
+
// src/ratelimit/in-memory-rate-limiter.ts
|
|
2816
|
+
var InMemoryRateLimiter = class {
|
|
2817
|
+
static {
|
|
2818
|
+
__name(this, "InMemoryRateLimiter");
|
|
2819
|
+
}
|
|
2820
|
+
options;
|
|
2821
|
+
buckets = /* @__PURE__ */ new Map();
|
|
2822
|
+
now;
|
|
2823
|
+
constructor(options) {
|
|
2824
|
+
this.options = options;
|
|
2825
|
+
this.now = options.now ?? Date.now;
|
|
2826
|
+
}
|
|
2827
|
+
async consume(key, cost = 1) {
|
|
2828
|
+
const now = this.now();
|
|
2829
|
+
const bucket = this.buckets.get(key) ?? {
|
|
2830
|
+
tokens: this.options.capacity,
|
|
2831
|
+
last: now
|
|
2832
|
+
};
|
|
2833
|
+
const elapsed = now - bucket.last;
|
|
2834
|
+
if (elapsed > 0) {
|
|
2835
|
+
const refill = elapsed / this.options.intervalMs * this.options.refillTokens;
|
|
2836
|
+
bucket.tokens = Math.min(this.options.capacity, bucket.tokens + refill);
|
|
2837
|
+
bucket.last = now;
|
|
2838
|
+
}
|
|
2839
|
+
let allowed = false;
|
|
2840
|
+
if (bucket.tokens >= cost) {
|
|
2841
|
+
bucket.tokens -= cost;
|
|
2842
|
+
allowed = true;
|
|
2843
|
+
}
|
|
2844
|
+
this.buckets.set(key, bucket);
|
|
2845
|
+
return allowed;
|
|
2846
|
+
}
|
|
2847
|
+
};
|
|
2848
|
+
function _ts_decorate31(decorators, target, key, desc) {
|
|
2849
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
2850
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
2851
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
2852
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
2853
|
+
}
|
|
2854
|
+
__name(_ts_decorate31, "_ts_decorate");
|
|
2855
|
+
var DEFAULT_PII_PATTERNS = [
|
|
2856
|
+
/[\w.+-]+@[\w-]+\.[\w.-]+/g,
|
|
2857
|
+
/\b\d{3}-\d{2}-\d{4}\b/g,
|
|
2858
|
+
/\b(?:\d[ -]*?){13,16}\b/g,
|
|
2859
|
+
/(?:\+?\d[\d\s().-]{7,}\d)/g
|
|
2860
|
+
];
|
|
2861
|
+
function redactPii(text, patterns = DEFAULT_PII_PATTERNS, replacement = "[REDACTED]") {
|
|
2862
|
+
let out = text;
|
|
2863
|
+
for (const pattern of patterns) {
|
|
2864
|
+
out = out.replace(pattern, replacement);
|
|
2865
|
+
}
|
|
2866
|
+
return out;
|
|
2867
|
+
}
|
|
2868
|
+
__name(redactPii, "redactPii");
|
|
2869
|
+
function redactMessages(messages, patterns = DEFAULT_PII_PATTERNS, replacement = "[REDACTED]") {
|
|
2870
|
+
for (const message of messages) {
|
|
2871
|
+
const content = message.content;
|
|
2872
|
+
if (typeof content === "string") {
|
|
2873
|
+
message.content = redactPii(content, patterns, replacement);
|
|
2874
|
+
} else if (Array.isArray(content)) {
|
|
2875
|
+
for (const part of content) {
|
|
2876
|
+
if (part && typeof part === "object" && typeof part.text === "string") {
|
|
2877
|
+
part.text = redactPii(part.text, patterns, replacement);
|
|
2878
|
+
}
|
|
2879
|
+
}
|
|
2880
|
+
}
|
|
2881
|
+
}
|
|
2882
|
+
}
|
|
2883
|
+
__name(redactMessages, "redactMessages");
|
|
2884
|
+
exports.PiiRedactionGuardrail = class PiiRedactionGuardrail {
|
|
2885
|
+
static {
|
|
2886
|
+
__name(this, "PiiRedactionGuardrail");
|
|
2887
|
+
}
|
|
2888
|
+
beforeRun(ctx) {
|
|
2889
|
+
redactMessages(ctx.messages);
|
|
2890
|
+
}
|
|
2891
|
+
};
|
|
2892
|
+
exports.PiiRedactionGuardrail = _ts_decorate31([
|
|
2893
|
+
Guardrail(),
|
|
2894
|
+
common.Injectable()
|
|
2895
|
+
], exports.PiiRedactionGuardrail);
|
|
2896
|
+
function createPiiRedactionGuardrail(options = {}) {
|
|
2897
|
+
const patterns = options.patterns ?? DEFAULT_PII_PATTERNS;
|
|
2898
|
+
const replacement = options.replacement ?? "[REDACTED]";
|
|
2899
|
+
let ConfiguredPiiRedaction = class ConfiguredPiiRedaction {
|
|
2900
|
+
static {
|
|
2901
|
+
__name(this, "ConfiguredPiiRedaction");
|
|
2902
|
+
}
|
|
2903
|
+
beforeRun(ctx) {
|
|
2904
|
+
redactMessages(ctx.messages, patterns, replacement);
|
|
2905
|
+
}
|
|
2906
|
+
};
|
|
2907
|
+
ConfiguredPiiRedaction = _ts_decorate31([
|
|
2908
|
+
Guardrail(),
|
|
2909
|
+
common.Injectable()
|
|
2910
|
+
], ConfiguredPiiRedaction);
|
|
2911
|
+
return ConfiguredPiiRedaction;
|
|
2912
|
+
}
|
|
2913
|
+
__name(createPiiRedactionGuardrail, "createPiiRedactionGuardrail");
|
|
2914
|
+
function _ts_decorate32(decorators, target, key, desc) {
|
|
2915
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
2916
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
2917
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
2918
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
2919
|
+
}
|
|
2920
|
+
__name(_ts_decorate32, "_ts_decorate");
|
|
2921
|
+
var ContentBlockedError = class extends Error {
|
|
2922
|
+
static {
|
|
2923
|
+
__name(this, "ContentBlockedError");
|
|
2924
|
+
}
|
|
2925
|
+
reason;
|
|
2926
|
+
constructor(reason) {
|
|
2927
|
+
super(`Content blocked by moderation: ${reason}`), this.reason = reason;
|
|
2928
|
+
this.name = "ContentBlockedError";
|
|
2929
|
+
}
|
|
2930
|
+
};
|
|
2931
|
+
function messagesText(messages) {
|
|
2932
|
+
return messages.map((m) => {
|
|
2933
|
+
const content = m.content;
|
|
2934
|
+
if (typeof content === "string") {
|
|
2935
|
+
return content;
|
|
2936
|
+
}
|
|
2937
|
+
if (Array.isArray(content)) {
|
|
2938
|
+
return content.map((p) => p && typeof p.text === "string" ? p.text : "").join(" ");
|
|
2939
|
+
}
|
|
2940
|
+
return "";
|
|
2941
|
+
}).join("\n");
|
|
2942
|
+
}
|
|
2943
|
+
__name(messagesText, "messagesText");
|
|
2944
|
+
function createModerationGuardrail(options = {}) {
|
|
2945
|
+
const blocked = (options.blocked ?? []).map((t) => t.toLowerCase());
|
|
2946
|
+
const moderate = options.moderate;
|
|
2947
|
+
let ConfiguredModeration = class ConfiguredModeration {
|
|
2948
|
+
static {
|
|
2949
|
+
__name(this, "ConfiguredModeration");
|
|
2950
|
+
}
|
|
2951
|
+
async beforeRun(ctx) {
|
|
2952
|
+
const text = messagesText(ctx.messages);
|
|
2953
|
+
const lower = text.toLowerCase();
|
|
2954
|
+
const hit = blocked.find((term) => lower.includes(term));
|
|
2955
|
+
if (hit) {
|
|
2956
|
+
throw new ContentBlockedError(`matched blocked term "${hit}"`);
|
|
2957
|
+
}
|
|
2958
|
+
if (moderate && await moderate(text)) {
|
|
2959
|
+
throw new ContentBlockedError("failed custom moderation");
|
|
2960
|
+
}
|
|
2961
|
+
}
|
|
2962
|
+
};
|
|
2963
|
+
ConfiguredModeration = _ts_decorate32([
|
|
2964
|
+
Guardrail(),
|
|
2965
|
+
common.Injectable()
|
|
2966
|
+
], ConfiguredModeration);
|
|
2967
|
+
return ConfiguredModeration;
|
|
2968
|
+
}
|
|
2969
|
+
__name(createModerationGuardrail, "createModerationGuardrail");
|
|
2970
|
+
function _ts_decorate33(decorators, target, key, desc) {
|
|
2971
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
2972
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
2973
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
2974
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
2975
|
+
}
|
|
2976
|
+
__name(_ts_decorate33, "_ts_decorate");
|
|
2977
|
+
function _ts_metadata23(k, v) {
|
|
2978
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
2979
|
+
}
|
|
2980
|
+
__name(_ts_metadata23, "_ts_metadata");
|
|
2981
|
+
exports.ModelReranker = class ModelReranker {
|
|
2982
|
+
static {
|
|
2983
|
+
__name(this, "ModelReranker");
|
|
2984
|
+
}
|
|
2985
|
+
providers;
|
|
2986
|
+
model;
|
|
2987
|
+
constructor(providers, model) {
|
|
2988
|
+
this.providers = providers;
|
|
2989
|
+
this.model = model;
|
|
2990
|
+
}
|
|
2991
|
+
async rerank(query, results, topN) {
|
|
2992
|
+
if (results.length === 0) {
|
|
2993
|
+
return [];
|
|
2994
|
+
}
|
|
2995
|
+
const { ranking } = await ai.rerank({
|
|
2996
|
+
model: this.providers.getRerankingModel(this.model),
|
|
2997
|
+
query,
|
|
2998
|
+
documents: results.map((r) => r.content),
|
|
2999
|
+
topN
|
|
3000
|
+
});
|
|
3001
|
+
return ranking.map((entry) => ({
|
|
3002
|
+
...results[entry.originalIndex],
|
|
3003
|
+
score: entry.score
|
|
3004
|
+
}));
|
|
3005
|
+
}
|
|
3006
|
+
};
|
|
3007
|
+
exports.ModelReranker = _ts_decorate33([
|
|
3008
|
+
common.Injectable(),
|
|
3009
|
+
_ts_metadata23("design:type", Function),
|
|
3010
|
+
_ts_metadata23("design:paramtypes", [
|
|
3011
|
+
typeof exports.ProviderRegistry === "undefined" ? Object : exports.ProviderRegistry,
|
|
3012
|
+
String
|
|
3013
|
+
])
|
|
3014
|
+
], exports.ModelReranker);
|
|
3015
|
+
|
|
3016
|
+
// src/rag/adapters/qdrant/qdrant-vector-store.ts
|
|
3017
|
+
var QdrantVectorStore = class {
|
|
3018
|
+
static {
|
|
3019
|
+
__name(this, "QdrantVectorStore");
|
|
3020
|
+
}
|
|
3021
|
+
client;
|
|
3022
|
+
options;
|
|
3023
|
+
constructor(client, options) {
|
|
3024
|
+
this.client = client;
|
|
3025
|
+
this.options = options;
|
|
3026
|
+
}
|
|
3027
|
+
async upsert(documents) {
|
|
3028
|
+
await this.client.upsert(this.options.collection, {
|
|
3029
|
+
wait: true,
|
|
3030
|
+
points: documents.map((doc) => {
|
|
3031
|
+
if (!doc.embedding) {
|
|
3032
|
+
throw new Error(`Document "${doc.id}" has no embedding.`);
|
|
3033
|
+
}
|
|
3034
|
+
return {
|
|
3035
|
+
id: doc.id,
|
|
3036
|
+
vector: doc.embedding,
|
|
3037
|
+
payload: {
|
|
3038
|
+
content: doc.content,
|
|
3039
|
+
...doc.metadata
|
|
3040
|
+
}
|
|
3041
|
+
};
|
|
3042
|
+
})
|
|
3043
|
+
});
|
|
3044
|
+
}
|
|
3045
|
+
async query(embedding, options = {}) {
|
|
3046
|
+
const results = await this.client.search(this.options.collection, {
|
|
3047
|
+
vector: embedding,
|
|
3048
|
+
limit: options.topK ?? 4,
|
|
3049
|
+
with_payload: true,
|
|
3050
|
+
filter: buildFilter(options.filter)
|
|
3051
|
+
});
|
|
3052
|
+
return results.map((hit) => {
|
|
3053
|
+
const { content, ...metadata } = hit.payload ?? {};
|
|
3054
|
+
return {
|
|
3055
|
+
id: String(hit.id),
|
|
3056
|
+
content: String(content ?? ""),
|
|
3057
|
+
score: hit.score,
|
|
3058
|
+
metadata: Object.keys(metadata).length ? metadata : void 0
|
|
3059
|
+
};
|
|
3060
|
+
});
|
|
3061
|
+
}
|
|
3062
|
+
async delete(ids) {
|
|
3063
|
+
await this.client.delete(this.options.collection, {
|
|
3064
|
+
points: ids
|
|
3065
|
+
});
|
|
3066
|
+
}
|
|
3067
|
+
async clear() {
|
|
3068
|
+
await this.client.delete(this.options.collection, {
|
|
3069
|
+
filter: {}
|
|
3070
|
+
});
|
|
3071
|
+
}
|
|
3072
|
+
};
|
|
3073
|
+
function buildFilter(filter) {
|
|
3074
|
+
if (!filter || Object.keys(filter).length === 0) {
|
|
3075
|
+
return void 0;
|
|
3076
|
+
}
|
|
3077
|
+
return {
|
|
3078
|
+
must: Object.entries(filter).map(([key, value]) => ({
|
|
3079
|
+
key,
|
|
3080
|
+
match: {
|
|
3081
|
+
value
|
|
3082
|
+
}
|
|
3083
|
+
}))
|
|
3084
|
+
};
|
|
3085
|
+
}
|
|
3086
|
+
__name(buildFilter, "buildFilter");
|
|
3087
|
+
|
|
3088
|
+
// src/rag/adapters/pinecone/pinecone-vector-store.ts
|
|
3089
|
+
var PineconeVectorStore = class {
|
|
3090
|
+
static {
|
|
3091
|
+
__name(this, "PineconeVectorStore");
|
|
3092
|
+
}
|
|
3093
|
+
index;
|
|
3094
|
+
constructor(index) {
|
|
3095
|
+
this.index = index;
|
|
3096
|
+
}
|
|
3097
|
+
async upsert(documents) {
|
|
3098
|
+
await this.index.upsert(documents.map((doc) => {
|
|
3099
|
+
if (!doc.embedding) {
|
|
3100
|
+
throw new Error(`Document "${doc.id}" has no embedding.`);
|
|
3101
|
+
}
|
|
3102
|
+
return {
|
|
3103
|
+
id: doc.id,
|
|
3104
|
+
values: doc.embedding,
|
|
3105
|
+
metadata: {
|
|
3106
|
+
content: doc.content,
|
|
3107
|
+
...doc.metadata
|
|
3108
|
+
}
|
|
3109
|
+
};
|
|
3110
|
+
}));
|
|
3111
|
+
}
|
|
3112
|
+
async query(embedding, options = {}) {
|
|
3113
|
+
const { matches } = await this.index.query({
|
|
3114
|
+
vector: embedding,
|
|
3115
|
+
topK: options.topK ?? 4,
|
|
3116
|
+
includeMetadata: true,
|
|
3117
|
+
filter: options.filter
|
|
3118
|
+
});
|
|
3119
|
+
return (matches ?? []).map((match) => {
|
|
3120
|
+
const { content, ...metadata } = match.metadata ?? {};
|
|
3121
|
+
return {
|
|
3122
|
+
id: match.id,
|
|
3123
|
+
content: String(content ?? ""),
|
|
3124
|
+
score: match.score ?? 0,
|
|
3125
|
+
metadata: Object.keys(metadata).length ? metadata : void 0
|
|
3126
|
+
};
|
|
3127
|
+
});
|
|
3128
|
+
}
|
|
3129
|
+
async delete(ids) {
|
|
3130
|
+
await this.index.deleteMany(ids);
|
|
3131
|
+
}
|
|
3132
|
+
async clear() {
|
|
3133
|
+
await this.index.deleteAll();
|
|
3134
|
+
}
|
|
3135
|
+
};
|
|
3136
|
+
|
|
3137
|
+
// src/websocket/stream-to-socket.ts
|
|
3138
|
+
async function streamAgentToSocket(stream, socket, options = {}) {
|
|
3139
|
+
const chunkEvent = options.chunkEvent ?? "agent:chunk";
|
|
3140
|
+
const doneEvent = options.doneEvent ?? "agent:done";
|
|
3141
|
+
const errorEvent = options.errorEvent ?? "agent:error";
|
|
3142
|
+
try {
|
|
3143
|
+
let text = "";
|
|
3144
|
+
for await (const delta of stream.textStream) {
|
|
3145
|
+
text += delta;
|
|
3146
|
+
socket.emit(chunkEvent, {
|
|
3147
|
+
delta
|
|
3148
|
+
});
|
|
3149
|
+
}
|
|
3150
|
+
socket.emit(doneEvent, {
|
|
3151
|
+
text
|
|
3152
|
+
});
|
|
3153
|
+
return text;
|
|
3154
|
+
} catch (error) {
|
|
3155
|
+
socket.emit(errorEvent, {
|
|
3156
|
+
message: error instanceof Error ? error.message : String(error)
|
|
3157
|
+
});
|
|
3158
|
+
throw error;
|
|
3159
|
+
}
|
|
3160
|
+
}
|
|
3161
|
+
__name(streamAgentToSocket, "streamAgentToSocket");
|
|
3162
|
+
|
|
3163
|
+
exports.AGENT_JOB_NAME = AGENT_JOB_NAME;
|
|
3164
|
+
exports.AGENT_QUEUE = AGENT_QUEUE;
|
|
3165
|
+
exports.AI_CACHE = AI_CACHE;
|
|
3166
|
+
exports.AI_EVENTS = AI_EVENTS;
|
|
3167
|
+
exports.AI_MODULE_OPTIONS = AI_MODULE_OPTIONS;
|
|
3168
|
+
exports.APPROVAL_GATE = APPROVAL_GATE;
|
|
3169
|
+
exports.Agent = Agent;
|
|
3170
|
+
exports.AiAgent = AiAgent;
|
|
3171
|
+
exports.BudgetExceededError = BudgetExceededError;
|
|
3172
|
+
exports.CONVERSATION_STORE = CONVERSATION_STORE;
|
|
3173
|
+
exports.ContentBlockedError = ContentBlockedError;
|
|
3174
|
+
exports.DEFAULT_MAX_STEPS = DEFAULT_MAX_STEPS;
|
|
3175
|
+
exports.DEFAULT_PII_PATTERNS = DEFAULT_PII_PATTERNS;
|
|
3176
|
+
exports.DEFAULT_PRICING = DEFAULT_PRICING;
|
|
3177
|
+
exports.EVENT_EMITTER = EVENT_EMITTER;
|
|
3178
|
+
exports.Guardrail = Guardrail;
|
|
3179
|
+
exports.InMemoryRateLimiter = InMemoryRateLimiter;
|
|
3180
|
+
exports.PgVectorStore = PgVectorStore;
|
|
3181
|
+
exports.PineconeVectorStore = PineconeVectorStore;
|
|
3182
|
+
exports.PrismaConversationStore = PrismaConversationStore;
|
|
3183
|
+
exports.QdrantVectorStore = QdrantVectorStore;
|
|
3184
|
+
exports.RATE_LIMITER = RATE_LIMITER;
|
|
3185
|
+
exports.RERANKER = RERANKER;
|
|
3186
|
+
exports.RateLimitedError = RateLimitedError;
|
|
3187
|
+
exports.Tool = Tool;
|
|
3188
|
+
exports.ToolApprovalDeniedError = ToolApprovalDeniedError;
|
|
3189
|
+
exports.VECTOR_STORE = VECTOR_STORE;
|
|
3190
|
+
exports.bareModelId = bareModelId;
|
|
3191
|
+
exports.cacheKey = cacheKey;
|
|
3192
|
+
exports.costOf = costOf;
|
|
3193
|
+
exports.createAgentTool = createAgentTool;
|
|
3194
|
+
exports.createCacheMiddleware = createCacheMiddleware;
|
|
3195
|
+
exports.createFallbackModel = createFallbackModel;
|
|
3196
|
+
exports.createLlmJudge = createLlmJudge;
|
|
3197
|
+
exports.createModerationGuardrail = createModerationGuardrail;
|
|
3198
|
+
exports.createPiiRedactionGuardrail = createPiiRedactionGuardrail;
|
|
3199
|
+
exports.createRetrievalTool = createRetrievalTool;
|
|
3200
|
+
exports.defaultJudge = defaultJudge;
|
|
3201
|
+
exports.interpolate = interpolate;
|
|
3202
|
+
exports.pipeAgentStream = pipeAgentStream;
|
|
3203
|
+
exports.redactMessages = redactMessages;
|
|
3204
|
+
exports.redactPii = redactPii;
|
|
3205
|
+
exports.splitText = splitText;
|
|
3206
|
+
exports.streamAgentToSocket = streamAgentToSocket;
|
|
3207
|
+
exports.toMessages = toMessages;
|
|
3208
|
+
//# sourceMappingURL=index.cjs.map
|
|
3209
|
+
//# sourceMappingURL=index.cjs.map
|