@promptbook/wizard 0.110.0-4 → 0.110.0-7
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/esm/index.es.js +1220 -406
- package/esm/index.es.js.map +1 -1
- package/esm/typings/src/_packages/openai.index.d.ts +8 -4
- package/esm/typings/src/_packages/types.index.d.ts +4 -2
- package/esm/typings/src/collection/agent-collection/constructors/agent-collection-in-supabase/AgentsDatabaseSchema.d.ts +0 -3
- package/esm/typings/src/execution/LlmExecutionTools.d.ts +2 -1
- package/esm/typings/src/llm-providers/agent/Agent.d.ts +1 -1
- package/esm/typings/src/llm-providers/agent/AgentLlmExecutionTools.d.ts +5 -1
- package/esm/typings/src/llm-providers/agent/AgentOptions.d.ts +4 -3
- package/esm/typings/src/llm-providers/agent/CreateAgentLlmExecutionToolsOptions.d.ts +7 -5
- package/esm/typings/src/llm-providers/agent/RemoteAgent.d.ts +2 -1
- package/esm/typings/src/llm-providers/openai/OpenAiAgentKitExecutionTools.d.ts +111 -0
- package/esm/typings/src/llm-providers/openai/OpenAiAgentKitExecutionToolsOptions.d.ts +15 -0
- package/esm/typings/src/llm-providers/openai/OpenAiAssistantExecutionTools.d.ts +3 -3
- package/esm/typings/src/llm-providers/openai/OpenAiAssistantExecutionToolsOptions.d.ts +2 -3
- package/esm/typings/src/llm-providers/openai/OpenAiVectorStoreHandler.d.ts +135 -0
- package/esm/typings/src/llm-providers/openai/utils/mapToolsToOpenAi.d.ts +1 -1
- package/esm/typings/src/version.d.ts +1 -1
- package/package.json +7 -3
- package/umd/index.umd.js +1223 -410
- package/umd/index.umd.js.map +1 -1
- package/esm/typings/src/llm-providers/openai/OpenAiAgentExecutionTools.d.ts +0 -43
- package/esm/typings/src/llm-providers/openai/createOpenAiAgentExecutionTools.d.ts +0 -11
package/esm/index.es.js
CHANGED
|
@@ -21,6 +21,7 @@ import { Subject, BehaviorSubject } from 'rxjs';
|
|
|
21
21
|
import moment from 'moment';
|
|
22
22
|
import { lookup, extension } from 'mime-types';
|
|
23
23
|
import { parse, unparse } from 'papaparse';
|
|
24
|
+
import { Agent as Agent$1, setDefaultOpenAIClient, setDefaultOpenAIKey, fileSearchTool, tool, run } from '@openai/agents';
|
|
24
25
|
import OpenAI from 'openai';
|
|
25
26
|
|
|
26
27
|
// ⚠️ WARNING: This code has been generated so that any manual changes will be overwritten
|
|
@@ -37,7 +38,7 @@ const BOOK_LANGUAGE_VERSION = '2.0.0';
|
|
|
37
38
|
* @generated
|
|
38
39
|
* @see https://github.com/webgptorg/promptbook
|
|
39
40
|
*/
|
|
40
|
-
const PROMPTBOOK_ENGINE_VERSION = '0.110.0-
|
|
41
|
+
const PROMPTBOOK_ENGINE_VERSION = '0.110.0-7';
|
|
41
42
|
/**
|
|
42
43
|
* TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
|
|
43
44
|
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
@@ -8699,16 +8700,11 @@ class OpenAiCompatibleExecutionTools {
|
|
|
8699
8700
|
const openAiOptions = { ...this.options };
|
|
8700
8701
|
delete openAiOptions.isVerbose;
|
|
8701
8702
|
delete openAiOptions.userId;
|
|
8702
|
-
// Enhanced configuration
|
|
8703
|
+
// Enhanced configuration with retries and timeouts.
|
|
8703
8704
|
const enhancedOptions = {
|
|
8704
8705
|
...openAiOptions,
|
|
8705
8706
|
timeout: API_REQUEST_TIMEOUT,
|
|
8706
8707
|
maxRetries: CONNECTION_RETRIES_LIMIT,
|
|
8707
|
-
defaultHeaders: {
|
|
8708
|
-
Connection: 'keep-alive',
|
|
8709
|
-
'Keep-Alive': 'timeout=30, max=100',
|
|
8710
|
-
...openAiOptions.defaultHeaders,
|
|
8711
|
-
},
|
|
8712
8708
|
};
|
|
8713
8709
|
this.client = new OpenAI(enhancedOptions);
|
|
8714
8710
|
}
|
|
@@ -10094,18 +10090,6 @@ class OpenAiExecutionTools extends OpenAiCompatibleExecutionTools {
|
|
|
10094
10090
|
get profile() {
|
|
10095
10091
|
return OPENAI_PROVIDER_PROFILE;
|
|
10096
10092
|
}
|
|
10097
|
-
/*
|
|
10098
|
-
Note: Commenting this out to avoid circular dependency
|
|
10099
|
-
/**
|
|
10100
|
-
* Create (sub)tools for calling OpenAI API Assistants
|
|
10101
|
-
*
|
|
10102
|
-
* @param assistantId Which assistant to use
|
|
10103
|
-
* @returns Tools for calling OpenAI API Assistants with same token
|
|
10104
|
-
* /
|
|
10105
|
-
public createAssistantSubtools(assistantId: string_token): OpenAiAssistantExecutionTools {
|
|
10106
|
-
return new OpenAiAssistantExecutionTools({ ...this.options, assistantId });
|
|
10107
|
-
}
|
|
10108
|
-
*/
|
|
10109
10093
|
/**
|
|
10110
10094
|
* List all available models (non dynamically)
|
|
10111
10095
|
*
|
|
@@ -10140,6 +10124,754 @@ class OpenAiExecutionTools extends OpenAiCompatibleExecutionTools {
|
|
|
10140
10124
|
}
|
|
10141
10125
|
}
|
|
10142
10126
|
|
|
10127
|
+
const DEFAULT_KNOWLEDGE_SOURCE_DOWNLOAD_TIMEOUT_MS = 30000;
|
|
10128
|
+
const DEFAULT_KNOWLEDGE_SOURCE_UPLOAD_TIMEOUT_MS = 900000;
|
|
10129
|
+
const VECTOR_STORE_PROGRESS_LOG_INTERVAL_MIN_MS = 15000;
|
|
10130
|
+
const VECTOR_STORE_STALL_LOG_THRESHOLD_MS = 30000;
|
|
10131
|
+
/**
|
|
10132
|
+
* Base class for OpenAI execution tools that need hosted vector stores.
|
|
10133
|
+
*
|
|
10134
|
+
* @public exported from `@promptbook/openai`
|
|
10135
|
+
*/
|
|
10136
|
+
class OpenAiVectorStoreHandler extends OpenAiExecutionTools {
|
|
10137
|
+
/**
|
|
10138
|
+
* Returns the per-knowledge-source download timeout in milliseconds.
|
|
10139
|
+
*/
|
|
10140
|
+
getKnowledgeSourceDownloadTimeoutMs() {
|
|
10141
|
+
var _a;
|
|
10142
|
+
return (_a = this.vectorStoreOptions.knowledgeSourceDownloadTimeoutMs) !== null && _a !== void 0 ? _a : DEFAULT_KNOWLEDGE_SOURCE_DOWNLOAD_TIMEOUT_MS;
|
|
10143
|
+
}
|
|
10144
|
+
/**
|
|
10145
|
+
* Returns the max concurrency for knowledge source uploads.
|
|
10146
|
+
*/
|
|
10147
|
+
getKnowledgeSourceUploadMaxConcurrency() {
|
|
10148
|
+
var _a;
|
|
10149
|
+
return (_a = this.vectorStoreOptions.knowledgeSourceUploadMaxConcurrency) !== null && _a !== void 0 ? _a : 5;
|
|
10150
|
+
}
|
|
10151
|
+
/**
|
|
10152
|
+
* Returns the polling interval in milliseconds for vector store uploads.
|
|
10153
|
+
*/
|
|
10154
|
+
getKnowledgeSourceUploadPollIntervalMs() {
|
|
10155
|
+
var _a;
|
|
10156
|
+
return (_a = this.vectorStoreOptions.knowledgeSourceUploadPollIntervalMs) !== null && _a !== void 0 ? _a : 5000;
|
|
10157
|
+
}
|
|
10158
|
+
/**
|
|
10159
|
+
* Returns the overall upload timeout in milliseconds for vector store uploads.
|
|
10160
|
+
*/
|
|
10161
|
+
getKnowledgeSourceUploadTimeoutMs() {
|
|
10162
|
+
var _a;
|
|
10163
|
+
return (_a = this.vectorStoreOptions.knowledgeSourceUploadTimeoutMs) !== null && _a !== void 0 ? _a : DEFAULT_KNOWLEDGE_SOURCE_UPLOAD_TIMEOUT_MS;
|
|
10164
|
+
}
|
|
10165
|
+
/**
|
|
10166
|
+
* Returns true if we should continue even if vector store ingestion stalls.
|
|
10167
|
+
*/
|
|
10168
|
+
shouldContinueOnVectorStoreStall() {
|
|
10169
|
+
var _a;
|
|
10170
|
+
return (_a = this.vectorStoreOptions.shouldContinueOnVectorStoreStall) !== null && _a !== void 0 ? _a : true;
|
|
10171
|
+
}
|
|
10172
|
+
/**
|
|
10173
|
+
* Returns vector-store-specific options with extended settings.
|
|
10174
|
+
*/
|
|
10175
|
+
get vectorStoreOptions() {
|
|
10176
|
+
return this.options;
|
|
10177
|
+
}
|
|
10178
|
+
/**
|
|
10179
|
+
* Returns the OpenAI vector stores API surface, supporting stable and beta SDKs.
|
|
10180
|
+
*/
|
|
10181
|
+
getVectorStoresApi(client) {
|
|
10182
|
+
var _a, _b;
|
|
10183
|
+
const vectorStores = (_a = client.vectorStores) !== null && _a !== void 0 ? _a : (_b = client.beta) === null || _b === void 0 ? void 0 : _b.vectorStores;
|
|
10184
|
+
if (!vectorStores) {
|
|
10185
|
+
throw new Error('OpenAI client does not support vector stores. Please ensure you are using a compatible version of the OpenAI SDK with vector store support.');
|
|
10186
|
+
}
|
|
10187
|
+
return vectorStores;
|
|
10188
|
+
}
|
|
10189
|
+
/**
|
|
10190
|
+
* Downloads a knowledge source URL into a File for vector store upload.
|
|
10191
|
+
*/
|
|
10192
|
+
async downloadKnowledgeSourceFile(options) {
|
|
10193
|
+
var _a;
|
|
10194
|
+
const { source, timeoutMs, logLabel } = options;
|
|
10195
|
+
const startedAtMs = Date.now();
|
|
10196
|
+
const controller = new AbortController();
|
|
10197
|
+
const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
|
|
10198
|
+
if (this.options.isVerbose) {
|
|
10199
|
+
console.info('[🤰]', 'Downloading knowledge source', {
|
|
10200
|
+
source,
|
|
10201
|
+
timeoutMs,
|
|
10202
|
+
logLabel,
|
|
10203
|
+
});
|
|
10204
|
+
}
|
|
10205
|
+
try {
|
|
10206
|
+
const response = await fetch(source, { signal: controller.signal });
|
|
10207
|
+
const contentType = (_a = response.headers.get('content-type')) !== null && _a !== void 0 ? _a : undefined;
|
|
10208
|
+
if (!response.ok) {
|
|
10209
|
+
console.error('[🤰]', 'Failed to download knowledge source', {
|
|
10210
|
+
source,
|
|
10211
|
+
status: response.status,
|
|
10212
|
+
statusText: response.statusText,
|
|
10213
|
+
contentType,
|
|
10214
|
+
elapsedMs: Date.now() - startedAtMs,
|
|
10215
|
+
logLabel,
|
|
10216
|
+
});
|
|
10217
|
+
return null;
|
|
10218
|
+
}
|
|
10219
|
+
const buffer = await response.arrayBuffer();
|
|
10220
|
+
let filename = source.split('/').pop() || 'downloaded-file';
|
|
10221
|
+
try {
|
|
10222
|
+
const url = new URL(source);
|
|
10223
|
+
filename = url.pathname.split('/').pop() || filename;
|
|
10224
|
+
}
|
|
10225
|
+
catch (error) {
|
|
10226
|
+
// Keep default filename
|
|
10227
|
+
}
|
|
10228
|
+
const file = new File([buffer], filename, contentType ? { type: contentType } : undefined);
|
|
10229
|
+
const elapsedMs = Date.now() - startedAtMs;
|
|
10230
|
+
const sizeBytes = buffer.byteLength;
|
|
10231
|
+
if (this.options.isVerbose) {
|
|
10232
|
+
console.info('[🤰]', 'Downloaded knowledge source', {
|
|
10233
|
+
source,
|
|
10234
|
+
filename,
|
|
10235
|
+
sizeBytes,
|
|
10236
|
+
contentType,
|
|
10237
|
+
elapsedMs,
|
|
10238
|
+
logLabel,
|
|
10239
|
+
});
|
|
10240
|
+
}
|
|
10241
|
+
return { file, sizeBytes, filename, elapsedMs };
|
|
10242
|
+
}
|
|
10243
|
+
catch (error) {
|
|
10244
|
+
assertsError(error);
|
|
10245
|
+
console.error('[🤰]', 'Error downloading knowledge source', {
|
|
10246
|
+
source,
|
|
10247
|
+
elapsedMs: Date.now() - startedAtMs,
|
|
10248
|
+
logLabel,
|
|
10249
|
+
error: serializeError(error),
|
|
10250
|
+
});
|
|
10251
|
+
return null;
|
|
10252
|
+
}
|
|
10253
|
+
finally {
|
|
10254
|
+
clearTimeout(timeoutId);
|
|
10255
|
+
}
|
|
10256
|
+
}
|
|
10257
|
+
/**
|
|
10258
|
+
* Logs vector store file batch diagnostics to help trace ingestion stalls or failures.
|
|
10259
|
+
*/
|
|
10260
|
+
async logVectorStoreFileBatchDiagnostics(options) {
|
|
10261
|
+
var _a, _b, _c, _d, _e;
|
|
10262
|
+
const { client, vectorStoreId, batchId, uploadedFiles, logLabel, reason } = options;
|
|
10263
|
+
if (reason === 'stalled' && !this.options.isVerbose) {
|
|
10264
|
+
return;
|
|
10265
|
+
}
|
|
10266
|
+
if (!batchId.startsWith('vsfb_')) {
|
|
10267
|
+
console.error('[🤰]', 'Vector store file batch diagnostics skipped (invalid batch id)', {
|
|
10268
|
+
vectorStoreId,
|
|
10269
|
+
batchId,
|
|
10270
|
+
reason,
|
|
10271
|
+
logLabel,
|
|
10272
|
+
});
|
|
10273
|
+
return;
|
|
10274
|
+
}
|
|
10275
|
+
const fileIdToMetadata = new Map();
|
|
10276
|
+
for (const file of uploadedFiles) {
|
|
10277
|
+
fileIdToMetadata.set(file.fileId, file);
|
|
10278
|
+
}
|
|
10279
|
+
try {
|
|
10280
|
+
const vectorStores = this.getVectorStoresApi(client);
|
|
10281
|
+
const limit = Math.min(100, Math.max(10, uploadedFiles.length));
|
|
10282
|
+
const batchFilesPage = await vectorStores.fileBatches.listFiles(batchId, {
|
|
10283
|
+
vector_store_id: vectorStoreId,
|
|
10284
|
+
limit,
|
|
10285
|
+
});
|
|
10286
|
+
const batchFiles = (_a = batchFilesPage.data) !== null && _a !== void 0 ? _a : [];
|
|
10287
|
+
const statusCounts = {
|
|
10288
|
+
in_progress: 0,
|
|
10289
|
+
completed: 0,
|
|
10290
|
+
failed: 0,
|
|
10291
|
+
cancelled: 0,
|
|
10292
|
+
};
|
|
10293
|
+
const errorSamples = [];
|
|
10294
|
+
const inProgressSamples = [];
|
|
10295
|
+
const batchFileIds = new Set();
|
|
10296
|
+
for (const file of batchFiles) {
|
|
10297
|
+
const status = (_b = file.status) !== null && _b !== void 0 ? _b : 'unknown';
|
|
10298
|
+
statusCounts[status] = ((_c = statusCounts[status]) !== null && _c !== void 0 ? _c : 0) + 1;
|
|
10299
|
+
const vectorStoreFileId = file.id;
|
|
10300
|
+
const uploadedFileId = (_d = file.file_id) !== null && _d !== void 0 ? _d : file.fileId;
|
|
10301
|
+
const fileId = uploadedFileId !== null && uploadedFileId !== void 0 ? uploadedFileId : vectorStoreFileId;
|
|
10302
|
+
batchFileIds.add(fileId);
|
|
10303
|
+
const metadata = fileIdToMetadata.get(fileId);
|
|
10304
|
+
if (status === 'failed') {
|
|
10305
|
+
errorSamples.push({
|
|
10306
|
+
fileId,
|
|
10307
|
+
status,
|
|
10308
|
+
error: (_e = file.last_error) === null || _e === void 0 ? void 0 : _e.message,
|
|
10309
|
+
filename: metadata === null || metadata === void 0 ? void 0 : metadata.filename,
|
|
10310
|
+
vectorStoreFileId: uploadedFileId ? vectorStoreFileId : undefined,
|
|
10311
|
+
});
|
|
10312
|
+
}
|
|
10313
|
+
if (status === 'in_progress') {
|
|
10314
|
+
inProgressSamples.push({
|
|
10315
|
+
fileId,
|
|
10316
|
+
filename: metadata === null || metadata === void 0 ? void 0 : metadata.filename,
|
|
10317
|
+
vectorStoreFileId: uploadedFileId ? vectorStoreFileId : undefined,
|
|
10318
|
+
});
|
|
10319
|
+
}
|
|
10320
|
+
}
|
|
10321
|
+
const missingSamples = uploadedFiles
|
|
10322
|
+
.filter((file) => !batchFileIds.has(file.fileId))
|
|
10323
|
+
.slice(0, 5)
|
|
10324
|
+
.map((file) => ({
|
|
10325
|
+
fileId: file.fileId,
|
|
10326
|
+
filename: file.filename,
|
|
10327
|
+
sizeBytes: file.sizeBytes,
|
|
10328
|
+
}));
|
|
10329
|
+
const vectorStore = await vectorStores.retrieve(vectorStoreId);
|
|
10330
|
+
const logPayload = {
|
|
10331
|
+
vectorStoreId,
|
|
10332
|
+
batchId,
|
|
10333
|
+
reason,
|
|
10334
|
+
vectorStoreStatus: vectorStore.status,
|
|
10335
|
+
vectorStoreFileCounts: vectorStore.file_counts,
|
|
10336
|
+
vectorStoreUsageBytes: vectorStore.usage_bytes,
|
|
10337
|
+
batchFileCount: batchFiles.length,
|
|
10338
|
+
statusCounts,
|
|
10339
|
+
errorSamples: errorSamples.slice(0, 5),
|
|
10340
|
+
inProgressSamples,
|
|
10341
|
+
missingFileCount: uploadedFiles.length - batchFileIds.size,
|
|
10342
|
+
missingSamples,
|
|
10343
|
+
logLabel,
|
|
10344
|
+
};
|
|
10345
|
+
const logFunction = reason === 'stalled' ? console.info : console.error;
|
|
10346
|
+
logFunction('[🤰]', 'Vector store file batch diagnostics', logPayload);
|
|
10347
|
+
}
|
|
10348
|
+
catch (error) {
|
|
10349
|
+
assertsError(error);
|
|
10350
|
+
console.error('[🤰]', 'Vector store file batch diagnostics failed', {
|
|
10351
|
+
vectorStoreId,
|
|
10352
|
+
batchId,
|
|
10353
|
+
reason,
|
|
10354
|
+
logLabel,
|
|
10355
|
+
error: serializeError(error),
|
|
10356
|
+
});
|
|
10357
|
+
}
|
|
10358
|
+
}
|
|
10359
|
+
/**
|
|
10360
|
+
* Uploads knowledge source files to the vector store and polls until processing completes.
|
|
10361
|
+
*/
|
|
10362
|
+
async uploadKnowledgeSourceFilesToVectorStore(options) {
|
|
10363
|
+
var _a, _b, _c, _d, _e, _f;
|
|
10364
|
+
const { client, vectorStoreId, files, totalBytes, logLabel } = options;
|
|
10365
|
+
const vectorStores = this.getVectorStoresApi(client);
|
|
10366
|
+
const uploadStartedAtMs = Date.now();
|
|
10367
|
+
const maxConcurrency = Math.max(1, this.getKnowledgeSourceUploadMaxConcurrency());
|
|
10368
|
+
const pollIntervalMs = Math.max(1000, this.getKnowledgeSourceUploadPollIntervalMs());
|
|
10369
|
+
const uploadTimeoutMs = Math.max(1000, this.getKnowledgeSourceUploadTimeoutMs());
|
|
10370
|
+
if (this.options.isVerbose) {
|
|
10371
|
+
console.info('[🤰]', 'Uploading knowledge source files to OpenAI', {
|
|
10372
|
+
vectorStoreId,
|
|
10373
|
+
fileCount: files.length,
|
|
10374
|
+
totalBytes,
|
|
10375
|
+
maxConcurrency,
|
|
10376
|
+
pollIntervalMs,
|
|
10377
|
+
uploadTimeoutMs,
|
|
10378
|
+
logLabel,
|
|
10379
|
+
});
|
|
10380
|
+
}
|
|
10381
|
+
const fileTypeSummary = {};
|
|
10382
|
+
for (const file of files) {
|
|
10383
|
+
const filename = (_a = file.name) !== null && _a !== void 0 ? _a : '';
|
|
10384
|
+
const extension = filename.includes('.')
|
|
10385
|
+
? (_c = (_b = filename.split('.').pop()) === null || _b === void 0 ? void 0 : _b.toLowerCase()) !== null && _c !== void 0 ? _c : 'unknown'
|
|
10386
|
+
: 'unknown';
|
|
10387
|
+
const sizeBytes = typeof file.size === 'number' ? file.size : 0;
|
|
10388
|
+
const summary = (_d = fileTypeSummary[extension]) !== null && _d !== void 0 ? _d : { count: 0, totalBytes: 0 };
|
|
10389
|
+
summary.count += 1;
|
|
10390
|
+
summary.totalBytes += sizeBytes;
|
|
10391
|
+
fileTypeSummary[extension] = summary;
|
|
10392
|
+
}
|
|
10393
|
+
if (this.options.isVerbose) {
|
|
10394
|
+
console.info('[🤰]', 'Knowledge source file summary', {
|
|
10395
|
+
vectorStoreId,
|
|
10396
|
+
fileCount: files.length,
|
|
10397
|
+
totalBytes,
|
|
10398
|
+
fileTypeSummary,
|
|
10399
|
+
logLabel,
|
|
10400
|
+
});
|
|
10401
|
+
}
|
|
10402
|
+
const fileEntries = files.map((file, index) => ({ file, index }));
|
|
10403
|
+
const fileIterator = fileEntries.values();
|
|
10404
|
+
const fileIds = [];
|
|
10405
|
+
const uploadedFiles = [];
|
|
10406
|
+
const failedUploads = [];
|
|
10407
|
+
let uploadedCount = 0;
|
|
10408
|
+
const processFiles = async (iterator) => {
|
|
10409
|
+
var _a, _b;
|
|
10410
|
+
for (const { file, index } of iterator) {
|
|
10411
|
+
const uploadIndex = index + 1;
|
|
10412
|
+
const filename = file.name || `knowledge-source-${uploadIndex}`;
|
|
10413
|
+
const extension = filename.includes('.')
|
|
10414
|
+
? (_b = (_a = filename.split('.').pop()) === null || _a === void 0 ? void 0 : _a.toLowerCase()) !== null && _b !== void 0 ? _b : 'unknown'
|
|
10415
|
+
: 'unknown';
|
|
10416
|
+
const sizeBytes = typeof file.size === 'number' ? file.size : undefined;
|
|
10417
|
+
const fileUploadStartedAtMs = Date.now();
|
|
10418
|
+
if (this.options.isVerbose) {
|
|
10419
|
+
console.info('[🤰]', 'Uploading knowledge source file', {
|
|
10420
|
+
index: uploadIndex,
|
|
10421
|
+
total: files.length,
|
|
10422
|
+
filename,
|
|
10423
|
+
extension,
|
|
10424
|
+
sizeBytes,
|
|
10425
|
+
logLabel,
|
|
10426
|
+
});
|
|
10427
|
+
}
|
|
10428
|
+
try {
|
|
10429
|
+
const uploaded = await client.files.create({ file, purpose: 'assistants' });
|
|
10430
|
+
fileIds.push(uploaded.id);
|
|
10431
|
+
uploadedFiles.push({ fileId: uploaded.id, filename, sizeBytes });
|
|
10432
|
+
uploadedCount += 1;
|
|
10433
|
+
if (this.options.isVerbose) {
|
|
10434
|
+
console.info('[🤰]', 'Uploaded knowledge source file', {
|
|
10435
|
+
index: uploadIndex,
|
|
10436
|
+
total: files.length,
|
|
10437
|
+
filename,
|
|
10438
|
+
sizeBytes,
|
|
10439
|
+
fileId: uploaded.id,
|
|
10440
|
+
elapsedMs: Date.now() - fileUploadStartedAtMs,
|
|
10441
|
+
logLabel,
|
|
10442
|
+
});
|
|
10443
|
+
}
|
|
10444
|
+
}
|
|
10445
|
+
catch (error) {
|
|
10446
|
+
assertsError(error);
|
|
10447
|
+
const serializedError = serializeError(error);
|
|
10448
|
+
failedUploads.push({ index: uploadIndex, filename, error: serializedError });
|
|
10449
|
+
console.error('[🤰]', 'Failed to upload knowledge source file', {
|
|
10450
|
+
index: uploadIndex,
|
|
10451
|
+
total: files.length,
|
|
10452
|
+
filename,
|
|
10453
|
+
sizeBytes,
|
|
10454
|
+
elapsedMs: Date.now() - fileUploadStartedAtMs,
|
|
10455
|
+
logLabel,
|
|
10456
|
+
error: serializedError,
|
|
10457
|
+
});
|
|
10458
|
+
}
|
|
10459
|
+
}
|
|
10460
|
+
};
|
|
10461
|
+
const workerCount = Math.min(maxConcurrency, files.length);
|
|
10462
|
+
const workers = Array.from({ length: workerCount }, () => processFiles(fileIterator));
|
|
10463
|
+
await Promise.all(workers);
|
|
10464
|
+
if (this.options.isVerbose) {
|
|
10465
|
+
console.info('[🤰]', 'Finished uploading knowledge source files', {
|
|
10466
|
+
vectorStoreId,
|
|
10467
|
+
fileCount: files.length,
|
|
10468
|
+
uploadedCount,
|
|
10469
|
+
failedCount: failedUploads.length,
|
|
10470
|
+
elapsedMs: Date.now() - uploadStartedAtMs,
|
|
10471
|
+
failedSamples: failedUploads.slice(0, 3),
|
|
10472
|
+
logLabel,
|
|
10473
|
+
});
|
|
10474
|
+
}
|
|
10475
|
+
if (fileIds.length === 0) {
|
|
10476
|
+
console.error('[🤰]', 'No knowledge source files were uploaded', {
|
|
10477
|
+
vectorStoreId,
|
|
10478
|
+
fileCount: files.length,
|
|
10479
|
+
failedCount: failedUploads.length,
|
|
10480
|
+
logLabel,
|
|
10481
|
+
});
|
|
10482
|
+
return null;
|
|
10483
|
+
}
|
|
10484
|
+
const batch = await vectorStores.fileBatches.create(vectorStoreId, {
|
|
10485
|
+
file_ids: fileIds,
|
|
10486
|
+
});
|
|
10487
|
+
const expectedBatchId = batch.id;
|
|
10488
|
+
const expectedBatchIdValid = expectedBatchId.startsWith('vsfb_');
|
|
10489
|
+
if (!expectedBatchIdValid) {
|
|
10490
|
+
console.error('[🤰]', 'Vector store file batch id looks invalid', {
|
|
10491
|
+
vectorStoreId,
|
|
10492
|
+
batchId: expectedBatchId,
|
|
10493
|
+
batchVectorStoreId: batch.vector_store_id,
|
|
10494
|
+
logLabel,
|
|
10495
|
+
});
|
|
10496
|
+
}
|
|
10497
|
+
else if (batch.vector_store_id !== vectorStoreId) {
|
|
10498
|
+
console.error('[🤰]', 'Vector store file batch vector store id mismatch', {
|
|
10499
|
+
vectorStoreId,
|
|
10500
|
+
batchId: expectedBatchId,
|
|
10501
|
+
batchVectorStoreId: batch.vector_store_id,
|
|
10502
|
+
logLabel,
|
|
10503
|
+
});
|
|
10504
|
+
}
|
|
10505
|
+
if (this.options.isVerbose) {
|
|
10506
|
+
console.info('[🤰]', 'Created vector store file batch', {
|
|
10507
|
+
vectorStoreId,
|
|
10508
|
+
batchId: expectedBatchId,
|
|
10509
|
+
fileCount: fileIds.length,
|
|
10510
|
+
logLabel,
|
|
10511
|
+
});
|
|
10512
|
+
}
|
|
10513
|
+
const pollStartedAtMs = Date.now();
|
|
10514
|
+
const progressLogIntervalMs = Math.max(VECTOR_STORE_PROGRESS_LOG_INTERVAL_MIN_MS, pollIntervalMs);
|
|
10515
|
+
const diagnosticsIntervalMs = Math.max(60000, pollIntervalMs * 5);
|
|
10516
|
+
// let lastStatus: string | undefined;
|
|
10517
|
+
let lastCountsKey = '';
|
|
10518
|
+
let lastProgressKey = '';
|
|
10519
|
+
let lastLogAtMs = 0;
|
|
10520
|
+
let lastProgressAtMs = pollStartedAtMs;
|
|
10521
|
+
let lastDiagnosticsAtMs = pollStartedAtMs;
|
|
10522
|
+
let latestBatch = batch;
|
|
10523
|
+
let loggedBatchIdMismatch = false;
|
|
10524
|
+
let loggedBatchIdFallback = false;
|
|
10525
|
+
let loggedBatchIdInvalid = false;
|
|
10526
|
+
let shouldPoll = true;
|
|
10527
|
+
while (shouldPoll) {
|
|
10528
|
+
const nowMs = Date.now();
|
|
10529
|
+
// [🤰] Note: Sometimes OpenAI returns Vector Store object instead of Batch object, or IDs get swapped.
|
|
10530
|
+
const rawBatchId = typeof latestBatch.id === 'string' ? latestBatch.id : '';
|
|
10531
|
+
const rawVectorStoreId = latestBatch.vector_store_id;
|
|
10532
|
+
let returnedBatchId = rawBatchId;
|
|
10533
|
+
let returnedBatchIdValid = typeof returnedBatchId === 'string' && returnedBatchId.startsWith('vsfb_');
|
|
10534
|
+
if (!returnedBatchIdValid && expectedBatchIdValid) {
|
|
10535
|
+
if (!loggedBatchIdFallback) {
|
|
10536
|
+
console.error('[🤰]', 'Vector store file batch id missing from response; falling back to expected', {
|
|
10537
|
+
vectorStoreId,
|
|
10538
|
+
expectedBatchId,
|
|
10539
|
+
returnedBatchId,
|
|
10540
|
+
rawVectorStoreId,
|
|
10541
|
+
logLabel,
|
|
10542
|
+
});
|
|
10543
|
+
loggedBatchIdFallback = true;
|
|
10544
|
+
}
|
|
10545
|
+
returnedBatchId = expectedBatchId;
|
|
10546
|
+
returnedBatchIdValid = true;
|
|
10547
|
+
}
|
|
10548
|
+
if (!returnedBatchIdValid && !loggedBatchIdInvalid) {
|
|
10549
|
+
console.error('[🤰]', 'Vector store file batch id is invalid; stopping polling', {
|
|
10550
|
+
vectorStoreId,
|
|
10551
|
+
expectedBatchId,
|
|
10552
|
+
returnedBatchId,
|
|
10553
|
+
rawVectorStoreId,
|
|
10554
|
+
logLabel,
|
|
10555
|
+
});
|
|
10556
|
+
loggedBatchIdInvalid = true;
|
|
10557
|
+
}
|
|
10558
|
+
const batchIdMismatch = expectedBatchIdValid && returnedBatchIdValid && returnedBatchId !== expectedBatchId;
|
|
10559
|
+
if (batchIdMismatch && !loggedBatchIdMismatch) {
|
|
10560
|
+
console.error('[🤰]', 'Vector store file batch id mismatch', {
|
|
10561
|
+
vectorStoreId,
|
|
10562
|
+
expectedBatchId,
|
|
10563
|
+
returnedBatchId,
|
|
10564
|
+
logLabel,
|
|
10565
|
+
});
|
|
10566
|
+
loggedBatchIdMismatch = true;
|
|
10567
|
+
}
|
|
10568
|
+
if (returnedBatchIdValid) {
|
|
10569
|
+
latestBatch = await vectorStores.fileBatches.retrieve(returnedBatchId, {
|
|
10570
|
+
vector_store_id: vectorStoreId,
|
|
10571
|
+
});
|
|
10572
|
+
}
|
|
10573
|
+
else {
|
|
10574
|
+
shouldPoll = false;
|
|
10575
|
+
continue;
|
|
10576
|
+
}
|
|
10577
|
+
const status = (_e = latestBatch.status) !== null && _e !== void 0 ? _e : 'unknown';
|
|
10578
|
+
const fileCounts = (_f = latestBatch.file_counts) !== null && _f !== void 0 ? _f : {};
|
|
10579
|
+
const progressKey = JSON.stringify(fileCounts);
|
|
10580
|
+
const statusCountsKey = `${status}-${progressKey}`;
|
|
10581
|
+
const isProgressing = progressKey !== lastProgressKey;
|
|
10582
|
+
if (isProgressing) {
|
|
10583
|
+
lastProgressAtMs = nowMs;
|
|
10584
|
+
lastProgressKey = progressKey;
|
|
10585
|
+
}
|
|
10586
|
+
if (this.options.isVerbose &&
|
|
10587
|
+
(statusCountsKey !== lastCountsKey || nowMs - lastLogAtMs >= progressLogIntervalMs)) {
|
|
10588
|
+
console.info('[🤰]', 'Vector store file batch status', {
|
|
10589
|
+
vectorStoreId,
|
|
10590
|
+
batchId: returnedBatchId,
|
|
10591
|
+
status,
|
|
10592
|
+
fileCounts,
|
|
10593
|
+
elapsedMs: nowMs - pollStartedAtMs,
|
|
10594
|
+
logLabel,
|
|
10595
|
+
});
|
|
10596
|
+
lastCountsKey = statusCountsKey;
|
|
10597
|
+
lastLogAtMs = nowMs;
|
|
10598
|
+
}
|
|
10599
|
+
if (status === 'in_progress' &&
|
|
10600
|
+
nowMs - lastProgressAtMs >= VECTOR_STORE_STALL_LOG_THRESHOLD_MS &&
|
|
10601
|
+
nowMs - lastDiagnosticsAtMs >= diagnosticsIntervalMs) {
|
|
10602
|
+
lastDiagnosticsAtMs = nowMs;
|
|
10603
|
+
await this.logVectorStoreFileBatchDiagnostics({
|
|
10604
|
+
client,
|
|
10605
|
+
vectorStoreId,
|
|
10606
|
+
batchId: returnedBatchId,
|
|
10607
|
+
uploadedFiles,
|
|
10608
|
+
logLabel,
|
|
10609
|
+
reason: 'stalled',
|
|
10610
|
+
});
|
|
10611
|
+
}
|
|
10612
|
+
if (status === 'completed') {
|
|
10613
|
+
if (this.options.isVerbose) {
|
|
10614
|
+
console.info('[🤰]', 'Vector store file batch completed', {
|
|
10615
|
+
vectorStoreId,
|
|
10616
|
+
batchId: returnedBatchId,
|
|
10617
|
+
fileCounts,
|
|
10618
|
+
elapsedMs: nowMs - pollStartedAtMs,
|
|
10619
|
+
logLabel,
|
|
10620
|
+
});
|
|
10621
|
+
}
|
|
10622
|
+
shouldPoll = false;
|
|
10623
|
+
continue;
|
|
10624
|
+
}
|
|
10625
|
+
if (status === 'failed') {
|
|
10626
|
+
console.error('[🤰]', 'Vector store file batch completed with failures', {
|
|
10627
|
+
vectorStoreId,
|
|
10628
|
+
batchId: returnedBatchId,
|
|
10629
|
+
fileCounts,
|
|
10630
|
+
elapsedMs: nowMs - pollStartedAtMs,
|
|
10631
|
+
logLabel,
|
|
10632
|
+
});
|
|
10633
|
+
await this.logVectorStoreFileBatchDiagnostics({
|
|
10634
|
+
client,
|
|
10635
|
+
vectorStoreId,
|
|
10636
|
+
batchId: returnedBatchId,
|
|
10637
|
+
uploadedFiles,
|
|
10638
|
+
logLabel,
|
|
10639
|
+
reason: 'failed',
|
|
10640
|
+
});
|
|
10641
|
+
shouldPoll = false;
|
|
10642
|
+
continue;
|
|
10643
|
+
}
|
|
10644
|
+
if (status === 'cancelled') {
|
|
10645
|
+
console.error('[🤰]', 'Vector store file batch did not complete', {
|
|
10646
|
+
vectorStoreId,
|
|
10647
|
+
batchId: returnedBatchId,
|
|
10648
|
+
status,
|
|
10649
|
+
fileCounts,
|
|
10650
|
+
elapsedMs: nowMs - pollStartedAtMs,
|
|
10651
|
+
logLabel,
|
|
10652
|
+
});
|
|
10653
|
+
await this.logVectorStoreFileBatchDiagnostics({
|
|
10654
|
+
client,
|
|
10655
|
+
vectorStoreId,
|
|
10656
|
+
batchId: returnedBatchId,
|
|
10657
|
+
uploadedFiles,
|
|
10658
|
+
logLabel,
|
|
10659
|
+
reason: 'failed',
|
|
10660
|
+
});
|
|
10661
|
+
shouldPoll = false;
|
|
10662
|
+
continue;
|
|
10663
|
+
}
|
|
10664
|
+
if (nowMs - pollStartedAtMs >= uploadTimeoutMs) {
|
|
10665
|
+
console.error('[🤰]', 'Timed out waiting for vector store file batch', {
|
|
10666
|
+
vectorStoreId,
|
|
10667
|
+
batchId: returnedBatchId,
|
|
10668
|
+
fileCounts,
|
|
10669
|
+
elapsedMs: nowMs - pollStartedAtMs,
|
|
10670
|
+
uploadTimeoutMs,
|
|
10671
|
+
logLabel,
|
|
10672
|
+
});
|
|
10673
|
+
await this.logVectorStoreFileBatchDiagnostics({
|
|
10674
|
+
client,
|
|
10675
|
+
vectorStoreId,
|
|
10676
|
+
batchId: returnedBatchId,
|
|
10677
|
+
uploadedFiles,
|
|
10678
|
+
logLabel,
|
|
10679
|
+
reason: 'timeout',
|
|
10680
|
+
});
|
|
10681
|
+
if (this.shouldContinueOnVectorStoreStall()) {
|
|
10682
|
+
console.warn('[🤰]', 'Continuing despite vector store timeout as requested', {
|
|
10683
|
+
vectorStoreId,
|
|
10684
|
+
logLabel,
|
|
10685
|
+
});
|
|
10686
|
+
shouldPoll = false;
|
|
10687
|
+
continue;
|
|
10688
|
+
}
|
|
10689
|
+
try {
|
|
10690
|
+
const cancelBatchId = batchIdMismatch && returnedBatchId.startsWith('vsfb_') ? returnedBatchId : expectedBatchId;
|
|
10691
|
+
if (!cancelBatchId.startsWith('vsfb_')) {
|
|
10692
|
+
console.error('[🤰]', 'Skipping vector store file batch cancel (invalid batch id)', {
|
|
10693
|
+
vectorStoreId,
|
|
10694
|
+
batchId: cancelBatchId,
|
|
10695
|
+
logLabel,
|
|
10696
|
+
});
|
|
10697
|
+
}
|
|
10698
|
+
else {
|
|
10699
|
+
await vectorStores.fileBatches.cancel(cancelBatchId, {
|
|
10700
|
+
vector_store_id: vectorStoreId,
|
|
10701
|
+
});
|
|
10702
|
+
}
|
|
10703
|
+
if (this.options.isVerbose) {
|
|
10704
|
+
console.info('[🤰]', 'Cancelled vector store file batch after timeout', {
|
|
10705
|
+
vectorStoreId,
|
|
10706
|
+
batchId: batchIdMismatch && returnedBatchId.startsWith('vsfb_')
|
|
10707
|
+
? returnedBatchId
|
|
10708
|
+
: expectedBatchId,
|
|
10709
|
+
...(batchIdMismatch ? { returnedBatchId } : {}),
|
|
10710
|
+
logLabel,
|
|
10711
|
+
});
|
|
10712
|
+
}
|
|
10713
|
+
}
|
|
10714
|
+
catch (error) {
|
|
10715
|
+
assertsError(error);
|
|
10716
|
+
console.error('[🤰]', 'Failed to cancel vector store file batch after timeout', {
|
|
10717
|
+
vectorStoreId,
|
|
10718
|
+
batchId: expectedBatchId,
|
|
10719
|
+
...(batchIdMismatch ? { returnedBatchId } : {}),
|
|
10720
|
+
logLabel,
|
|
10721
|
+
error: serializeError(error),
|
|
10722
|
+
});
|
|
10723
|
+
}
|
|
10724
|
+
shouldPoll = false;
|
|
10725
|
+
continue;
|
|
10726
|
+
}
|
|
10727
|
+
await new Promise((resolve) => setTimeout(resolve, pollIntervalMs));
|
|
10728
|
+
}
|
|
10729
|
+
return latestBatch;
|
|
10730
|
+
}
|
|
10731
|
+
/**
|
|
10732
|
+
* Creates a vector store and uploads knowledge sources, returning its ID.
|
|
10733
|
+
*/
|
|
10734
|
+
async createVectorStoreWithKnowledgeSources(options) {
|
|
10735
|
+
const { client, name, knowledgeSources, logLabel } = options;
|
|
10736
|
+
const vectorStores = this.getVectorStoresApi(client);
|
|
10737
|
+
const knowledgeSourcesCount = knowledgeSources.length;
|
|
10738
|
+
const downloadTimeoutMs = this.getKnowledgeSourceDownloadTimeoutMs();
|
|
10739
|
+
if (this.options.isVerbose) {
|
|
10740
|
+
console.info('[🤰]', 'Creating vector store with knowledge sources', {
|
|
10741
|
+
name,
|
|
10742
|
+
knowledgeSourcesCount,
|
|
10743
|
+
downloadTimeoutMs,
|
|
10744
|
+
logLabel,
|
|
10745
|
+
});
|
|
10746
|
+
}
|
|
10747
|
+
const vectorStore = await vectorStores.create({
|
|
10748
|
+
name: `${name} Knowledge Base`,
|
|
10749
|
+
});
|
|
10750
|
+
const vectorStoreId = vectorStore.id;
|
|
10751
|
+
if (this.options.isVerbose) {
|
|
10752
|
+
console.info('[🤰]', 'Vector store created', {
|
|
10753
|
+
vectorStoreId,
|
|
10754
|
+
logLabel,
|
|
10755
|
+
});
|
|
10756
|
+
}
|
|
10757
|
+
const fileStreams = [];
|
|
10758
|
+
const skippedSources = [];
|
|
10759
|
+
let totalBytes = 0;
|
|
10760
|
+
const processingStartedAtMs = Date.now();
|
|
10761
|
+
for (const [index, source] of knowledgeSources.entries()) {
|
|
10762
|
+
try {
|
|
10763
|
+
const sourceType = source.startsWith('http') || source.startsWith('https') ? 'url' : 'file';
|
|
10764
|
+
if (this.options.isVerbose) {
|
|
10765
|
+
console.info('[🤰]', 'Processing knowledge source', {
|
|
10766
|
+
index: index + 1,
|
|
10767
|
+
total: knowledgeSourcesCount,
|
|
10768
|
+
source,
|
|
10769
|
+
sourceType,
|
|
10770
|
+
logLabel,
|
|
10771
|
+
});
|
|
10772
|
+
}
|
|
10773
|
+
// Check if it's a URL
|
|
10774
|
+
if (source.startsWith('http://') || source.startsWith('https://')) {
|
|
10775
|
+
const downloadResult = await this.downloadKnowledgeSourceFile({
|
|
10776
|
+
source,
|
|
10777
|
+
timeoutMs: downloadTimeoutMs,
|
|
10778
|
+
logLabel,
|
|
10779
|
+
});
|
|
10780
|
+
if (downloadResult) {
|
|
10781
|
+
fileStreams.push(downloadResult.file);
|
|
10782
|
+
totalBytes += downloadResult.sizeBytes;
|
|
10783
|
+
}
|
|
10784
|
+
else {
|
|
10785
|
+
skippedSources.push({ source, reason: 'download_failed' });
|
|
10786
|
+
}
|
|
10787
|
+
}
|
|
10788
|
+
else {
|
|
10789
|
+
skippedSources.push({ source, reason: 'unsupported_source_type' });
|
|
10790
|
+
if (this.options.isVerbose) {
|
|
10791
|
+
console.info('[🤰]', 'Skipping knowledge source (unsupported type)', {
|
|
10792
|
+
source,
|
|
10793
|
+
sourceType,
|
|
10794
|
+
logLabel,
|
|
10795
|
+
});
|
|
10796
|
+
}
|
|
10797
|
+
/*
|
|
10798
|
+
TODO: [🤰] Resolve problem with browser environment
|
|
10799
|
+
// Assume it's a local file path
|
|
10800
|
+
// Note: This will work in Node.js environment
|
|
10801
|
+
// For browser environments, this would need different handling
|
|
10802
|
+
const fs = await import('fs');
|
|
10803
|
+
const fileStream = fs.createReadStream(source);
|
|
10804
|
+
fileStreams.push(fileStream);
|
|
10805
|
+
*/
|
|
10806
|
+
}
|
|
10807
|
+
}
|
|
10808
|
+
catch (error) {
|
|
10809
|
+
assertsError(error);
|
|
10810
|
+
skippedSources.push({ source, reason: 'processing_error' });
|
|
10811
|
+
console.error('[🤰]', 'Error processing knowledge source', {
|
|
10812
|
+
source,
|
|
10813
|
+
logLabel,
|
|
10814
|
+
error: serializeError(error),
|
|
10815
|
+
});
|
|
10816
|
+
}
|
|
10817
|
+
}
|
|
10818
|
+
if (this.options.isVerbose) {
|
|
10819
|
+
console.info('[🤰]', 'Finished processing knowledge sources', {
|
|
10820
|
+
total: knowledgeSourcesCount,
|
|
10821
|
+
downloadedCount: fileStreams.length,
|
|
10822
|
+
skippedCount: skippedSources.length,
|
|
10823
|
+
totalBytes,
|
|
10824
|
+
elapsedMs: Date.now() - processingStartedAtMs,
|
|
10825
|
+
skippedSamples: skippedSources.slice(0, 3),
|
|
10826
|
+
logLabel,
|
|
10827
|
+
});
|
|
10828
|
+
}
|
|
10829
|
+
if (fileStreams.length > 0) {
|
|
10830
|
+
if (this.options.isVerbose) {
|
|
10831
|
+
console.info('[🤰]', 'Uploading files to vector store', {
|
|
10832
|
+
vectorStoreId,
|
|
10833
|
+
fileCount: fileStreams.length,
|
|
10834
|
+
totalBytes,
|
|
10835
|
+
maxConcurrency: this.getKnowledgeSourceUploadMaxConcurrency(),
|
|
10836
|
+
pollIntervalMs: this.getKnowledgeSourceUploadPollIntervalMs(),
|
|
10837
|
+
uploadTimeoutMs: this.getKnowledgeSourceUploadTimeoutMs(),
|
|
10838
|
+
logLabel,
|
|
10839
|
+
});
|
|
10840
|
+
}
|
|
10841
|
+
try {
|
|
10842
|
+
await this.uploadKnowledgeSourceFilesToVectorStore({
|
|
10843
|
+
client,
|
|
10844
|
+
vectorStoreId,
|
|
10845
|
+
files: fileStreams,
|
|
10846
|
+
totalBytes,
|
|
10847
|
+
logLabel,
|
|
10848
|
+
});
|
|
10849
|
+
}
|
|
10850
|
+
catch (error) {
|
|
10851
|
+
assertsError(error);
|
|
10852
|
+
console.error('[🤰]', 'Error uploading files to vector store', {
|
|
10853
|
+
vectorStoreId,
|
|
10854
|
+
logLabel,
|
|
10855
|
+
error: serializeError(error),
|
|
10856
|
+
});
|
|
10857
|
+
}
|
|
10858
|
+
}
|
|
10859
|
+
else if (this.options.isVerbose) {
|
|
10860
|
+
console.info('[🤰]', 'No knowledge source files to upload', {
|
|
10861
|
+
vectorStoreId,
|
|
10862
|
+
skippedCount: skippedSources.length,
|
|
10863
|
+
logLabel,
|
|
10864
|
+
});
|
|
10865
|
+
}
|
|
10866
|
+
return {
|
|
10867
|
+
vectorStoreId,
|
|
10868
|
+
uploadedFileCount: fileStreams.length,
|
|
10869
|
+
skippedCount: skippedSources.length,
|
|
10870
|
+
totalBytes,
|
|
10871
|
+
};
|
|
10872
|
+
}
|
|
10873
|
+
}
|
|
10874
|
+
|
|
10143
10875
|
/**
|
|
10144
10876
|
* Uploads files to OpenAI and returns their IDs
|
|
10145
10877
|
*
|
|
@@ -10173,10 +10905,10 @@ async function uploadFilesToOpenAi(client, files) {
|
|
|
10173
10905
|
* - `OpenAiAssistantExecutionTools` - which is a specific implementation of `LlmExecutionTools` for OpenAI models with assistant capabilities, recommended for usage in `Agent` or `AgentLlmExecutionTools`
|
|
10174
10906
|
* - `RemoteAgent` - which is an `Agent` that connects to a Promptbook Agents Server
|
|
10175
10907
|
*
|
|
10908
|
+
* @deprecated Use `OpenAiAgentKitExecutionTools` instead.
|
|
10176
10909
|
* @public exported from `@promptbook/openai`
|
|
10177
|
-
* @deprecated Use `OpenAiAgentExecutionTools` instead which uses the new OpenAI Responses API
|
|
10178
10910
|
*/
|
|
10179
|
-
class OpenAiAssistantExecutionTools extends
|
|
10911
|
+
class OpenAiAssistantExecutionTools extends OpenAiVectorStoreHandler {
|
|
10180
10912
|
/**
|
|
10181
10913
|
* Creates OpenAI Execution Tools.
|
|
10182
10914
|
*
|
|
@@ -10305,8 +11037,7 @@ class OpenAiAssistantExecutionTools extends OpenAiExecutionTools {
|
|
|
10305
11037
|
console.info(colors.bgWhite('rawRequest (non-streaming with tools)'), JSON.stringify(rawRequest, null, 4));
|
|
10306
11038
|
}
|
|
10307
11039
|
// Create thread and run
|
|
10308
|
-
|
|
10309
|
-
let run = threadAndRun;
|
|
11040
|
+
let run = (await client.beta.threads.createAndRun(rawRequest));
|
|
10310
11041
|
const completedToolCalls = [];
|
|
10311
11042
|
const toolCallStartedAt = new Map();
|
|
10312
11043
|
// Poll until run completes or requires action
|
|
@@ -10401,14 +11132,14 @@ class OpenAiAssistantExecutionTools extends OpenAiExecutionTools {
|
|
|
10401
11132
|
}
|
|
10402
11133
|
}
|
|
10403
11134
|
// Submit tool outputs
|
|
10404
|
-
run = await client.beta.threads.runs.submitToolOutputs(run.thread_id, run.id, {
|
|
11135
|
+
run = (await client.beta.threads.runs.submitToolOutputs(run.thread_id, run.id, {
|
|
10405
11136
|
tool_outputs: toolOutputs,
|
|
10406
|
-
});
|
|
11137
|
+
}));
|
|
10407
11138
|
}
|
|
10408
11139
|
else {
|
|
10409
11140
|
// Wait a bit before polling again
|
|
10410
11141
|
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
10411
|
-
run = await client.beta.threads.runs.retrieve(run.thread_id, run.id);
|
|
11142
|
+
run = (await client.beta.threads.runs.retrieve(run.thread_id, run.id));
|
|
10412
11143
|
}
|
|
10413
11144
|
}
|
|
10414
11145
|
if (run.status !== 'completed') {
|
|
@@ -10633,88 +11364,13 @@ class OpenAiAssistantExecutionTools extends OpenAiExecutionTools {
|
|
|
10633
11364
|
let vectorStoreId;
|
|
10634
11365
|
// If knowledge sources are provided, create a vector store with them
|
|
10635
11366
|
if (knowledgeSources && knowledgeSources.length > 0) {
|
|
10636
|
-
|
|
10637
|
-
|
|
10638
|
-
|
|
10639
|
-
|
|
10640
|
-
|
|
10641
|
-
}
|
|
10642
|
-
// Create a vector store
|
|
10643
|
-
const vectorStore = await client.beta.vectorStores.create({
|
|
10644
|
-
name: `${name} Knowledge Base`,
|
|
11367
|
+
const vectorStoreResult = await this.createVectorStoreWithKnowledgeSources({
|
|
11368
|
+
client,
|
|
11369
|
+
name,
|
|
11370
|
+
knowledgeSources,
|
|
11371
|
+
logLabel: 'assistant creation',
|
|
10645
11372
|
});
|
|
10646
|
-
vectorStoreId =
|
|
10647
|
-
if (this.options.isVerbose) {
|
|
10648
|
-
console.info('[🤰]', 'Vector store created', {
|
|
10649
|
-
vectorStoreId,
|
|
10650
|
-
});
|
|
10651
|
-
}
|
|
10652
|
-
// Upload files from knowledge sources to the vector store
|
|
10653
|
-
const fileStreams = [];
|
|
10654
|
-
for (const [index, source] of knowledgeSources.entries()) {
|
|
10655
|
-
try {
|
|
10656
|
-
if (this.options.isVerbose) {
|
|
10657
|
-
console.info('[🤰]', 'Processing knowledge source', {
|
|
10658
|
-
index: index + 1,
|
|
10659
|
-
total: knowledgeSources.length,
|
|
10660
|
-
source,
|
|
10661
|
-
sourceType: source.startsWith('http') || source.startsWith('https') ? 'url' : 'file',
|
|
10662
|
-
});
|
|
10663
|
-
}
|
|
10664
|
-
// Check if it's a URL
|
|
10665
|
-
if (source.startsWith('http://') || source.startsWith('https://')) {
|
|
10666
|
-
// Download the file
|
|
10667
|
-
const response = await fetch(source);
|
|
10668
|
-
if (!response.ok) {
|
|
10669
|
-
console.error(`Failed to download ${source}: ${response.statusText}`);
|
|
10670
|
-
continue;
|
|
10671
|
-
}
|
|
10672
|
-
const buffer = await response.arrayBuffer();
|
|
10673
|
-
let filename = source.split('/').pop() || 'downloaded-file';
|
|
10674
|
-
try {
|
|
10675
|
-
const url = new URL(source);
|
|
10676
|
-
filename = url.pathname.split('/').pop() || filename;
|
|
10677
|
-
}
|
|
10678
|
-
catch (error) {
|
|
10679
|
-
// Keep default filename
|
|
10680
|
-
}
|
|
10681
|
-
const blob = new Blob([buffer]);
|
|
10682
|
-
const file = new File([blob], filename);
|
|
10683
|
-
fileStreams.push(file);
|
|
10684
|
-
}
|
|
10685
|
-
else {
|
|
10686
|
-
/*
|
|
10687
|
-
TODO: [🐱🚀] Resolve problem with browser environment
|
|
10688
|
-
// Assume it's a local file path
|
|
10689
|
-
// Note: This will work in Node.js environment
|
|
10690
|
-
// For browser environments, this would need different handling
|
|
10691
|
-
const fs = await import('fs');
|
|
10692
|
-
const fileStream = fs.createReadStream(source);
|
|
10693
|
-
fileStreams.push(fileStream);
|
|
10694
|
-
*/
|
|
10695
|
-
}
|
|
10696
|
-
}
|
|
10697
|
-
catch (error) {
|
|
10698
|
-
console.error(`Error processing knowledge source ${source}:`, error);
|
|
10699
|
-
}
|
|
10700
|
-
}
|
|
10701
|
-
// Batch upload files to the vector store
|
|
10702
|
-
if (fileStreams.length > 0) {
|
|
10703
|
-
try {
|
|
10704
|
-
await client.beta.vectorStores.fileBatches.uploadAndPoll(vectorStoreId, {
|
|
10705
|
-
files: fileStreams,
|
|
10706
|
-
});
|
|
10707
|
-
if (this.options.isVerbose) {
|
|
10708
|
-
console.info('[🤰]', 'Uploaded files to vector store', {
|
|
10709
|
-
vectorStoreId,
|
|
10710
|
-
fileCount: fileStreams.length,
|
|
10711
|
-
});
|
|
10712
|
-
}
|
|
10713
|
-
}
|
|
10714
|
-
catch (error) {
|
|
10715
|
-
console.error('Error uploading files to vector store:', error);
|
|
10716
|
-
}
|
|
10717
|
-
}
|
|
11373
|
+
vectorStoreId = vectorStoreResult.vectorStoreId;
|
|
10718
11374
|
}
|
|
10719
11375
|
// Create assistant with vector store attached
|
|
10720
11376
|
const assistantConfig = {
|
|
@@ -10763,109 +11419,32 @@ class OpenAiAssistantExecutionTools extends OpenAiExecutionTools {
|
|
|
10763
11419
|
async updateAssistant(options) {
|
|
10764
11420
|
var _a, _b, _c, _d;
|
|
10765
11421
|
if (!this.isCreatingNewAssistantsAllowed) {
|
|
10766
|
-
throw new NotAllowed(`Updating assistants is not allowed. Set \`isCreatingNewAssistantsAllowed: true\` in options to enable this feature.`);
|
|
10767
|
-
}
|
|
10768
|
-
const { assistantId, name, instructions, knowledgeSources, tools } = options;
|
|
10769
|
-
const preparationStartedAtMs = Date.now();
|
|
10770
|
-
const knowledgeSourcesCount = (_a = knowledgeSources === null || knowledgeSources === void 0 ? void 0 : knowledgeSources.length) !== null && _a !== void 0 ? _a : 0;
|
|
10771
|
-
const toolsCount = (_b = tools === null || tools === void 0 ? void 0 : tools.length) !== null && _b !== void 0 ? _b : 0;
|
|
10772
|
-
if (this.options.isVerbose) {
|
|
10773
|
-
console.info('[🤰]', 'Starting OpenAI assistant update', {
|
|
10774
|
-
assistantId,
|
|
10775
|
-
name,
|
|
10776
|
-
knowledgeSourcesCount,
|
|
10777
|
-
toolsCount,
|
|
10778
|
-
instructionsLength: (_c = instructions === null || instructions === void 0 ? void 0 : instructions.length) !== null && _c !== void 0 ? _c : 0,
|
|
10779
|
-
});
|
|
10780
|
-
}
|
|
10781
|
-
const client = await this.getClient();
|
|
10782
|
-
let vectorStoreId;
|
|
10783
|
-
// If knowledge sources are provided, create a vector store with them
|
|
10784
|
-
|
|
10785
|
-
|
|
10786
|
-
|
|
10787
|
-
|
|
10788
|
-
|
|
10789
|
-
|
|
10790
|
-
|
|
10791
|
-
|
|
10792
|
-
}
|
|
10793
|
-
// Create a vector store
|
|
10794
|
-
const vectorStore = await client.beta.vectorStores.create({
|
|
10795
|
-
name: `${name} Knowledge Base`,
|
|
10796
|
-
});
|
|
10797
|
-
vectorStoreId = vectorStore.id;
|
|
10798
|
-
if (this.options.isVerbose) {
|
|
10799
|
-
console.info('[🤰]', 'Vector store created for assistant update', {
|
|
10800
|
-
vectorStoreId,
|
|
10801
|
-
});
|
|
10802
|
-
}
|
|
10803
|
-
// Upload files from knowledge sources to the vector store
|
|
10804
|
-
const fileStreams = [];
|
|
10805
|
-
for (const [index, source] of knowledgeSources.entries()) {
|
|
10806
|
-
try {
|
|
10807
|
-
if (this.options.isVerbose) {
|
|
10808
|
-
console.info('[🤰]', 'Processing knowledge source for update', {
|
|
10809
|
-
index: index + 1,
|
|
10810
|
-
total: knowledgeSources.length,
|
|
10811
|
-
source,
|
|
10812
|
-
sourceType: source.startsWith('http') || source.startsWith('https') ? 'url' : 'file',
|
|
10813
|
-
});
|
|
10814
|
-
}
|
|
10815
|
-
// Check if it's a URL
|
|
10816
|
-
if (source.startsWith('http://') || source.startsWith('https://')) {
|
|
10817
|
-
// Download the file
|
|
10818
|
-
const response = await fetch(source);
|
|
10819
|
-
if (!response.ok) {
|
|
10820
|
-
console.error(`Failed to download ${source}: ${response.statusText}`);
|
|
10821
|
-
continue;
|
|
10822
|
-
}
|
|
10823
|
-
const buffer = await response.arrayBuffer();
|
|
10824
|
-
let filename = source.split('/').pop() || 'downloaded-file';
|
|
10825
|
-
try {
|
|
10826
|
-
const url = new URL(source);
|
|
10827
|
-
filename = url.pathname.split('/').pop() || filename;
|
|
10828
|
-
}
|
|
10829
|
-
catch (error) {
|
|
10830
|
-
// Keep default filename
|
|
10831
|
-
}
|
|
10832
|
-
const blob = new Blob([buffer]);
|
|
10833
|
-
const file = new File([blob], filename);
|
|
10834
|
-
fileStreams.push(file);
|
|
10835
|
-
}
|
|
10836
|
-
else {
|
|
10837
|
-
/*
|
|
10838
|
-
TODO: [🐱🚀] Resolve problem with browser environment
|
|
10839
|
-
// Assume it's a local file path
|
|
10840
|
-
// Note: This will work in Node.js environment
|
|
10841
|
-
// For browser environments, this would need different handling
|
|
10842
|
-
const fs = await import('fs');
|
|
10843
|
-
const fileStream = fs.createReadStream(source);
|
|
10844
|
-
fileStreams.push(fileStream);
|
|
10845
|
-
*/
|
|
10846
|
-
}
|
|
10847
|
-
}
|
|
10848
|
-
catch (error) {
|
|
10849
|
-
console.error(`Error processing knowledge source ${source}:`, error);
|
|
10850
|
-
}
|
|
10851
|
-
}
|
|
10852
|
-
// Batch upload files to the vector store
|
|
10853
|
-
if (fileStreams.length > 0) {
|
|
10854
|
-
try {
|
|
10855
|
-
await client.beta.vectorStores.fileBatches.uploadAndPoll(vectorStoreId, {
|
|
10856
|
-
files: fileStreams,
|
|
10857
|
-
});
|
|
10858
|
-
if (this.options.isVerbose) {
|
|
10859
|
-
console.info('[🤰]', 'Uploaded files to vector store for update', {
|
|
10860
|
-
vectorStoreId,
|
|
10861
|
-
fileCount: fileStreams.length,
|
|
10862
|
-
});
|
|
10863
|
-
}
|
|
10864
|
-
}
|
|
10865
|
-
catch (error) {
|
|
10866
|
-
console.error('Error uploading files to vector store:', error);
|
|
10867
|
-
}
|
|
10868
|
-
}
|
|
11422
|
+
throw new NotAllowed(`Updating assistants is not allowed. Set \`isCreatingNewAssistantsAllowed: true\` in options to enable this feature.`);
|
|
11423
|
+
}
|
|
11424
|
+
const { assistantId, name, instructions, knowledgeSources, tools } = options;
|
|
11425
|
+
const preparationStartedAtMs = Date.now();
|
|
11426
|
+
const knowledgeSourcesCount = (_a = knowledgeSources === null || knowledgeSources === void 0 ? void 0 : knowledgeSources.length) !== null && _a !== void 0 ? _a : 0;
|
|
11427
|
+
const toolsCount = (_b = tools === null || tools === void 0 ? void 0 : tools.length) !== null && _b !== void 0 ? _b : 0;
|
|
11428
|
+
if (this.options.isVerbose) {
|
|
11429
|
+
console.info('[🤰]', 'Starting OpenAI assistant update', {
|
|
11430
|
+
assistantId,
|
|
11431
|
+
name,
|
|
11432
|
+
knowledgeSourcesCount,
|
|
11433
|
+
toolsCount,
|
|
11434
|
+
instructionsLength: (_c = instructions === null || instructions === void 0 ? void 0 : instructions.length) !== null && _c !== void 0 ? _c : 0,
|
|
11435
|
+
});
|
|
11436
|
+
}
|
|
11437
|
+
const client = await this.getClient();
|
|
11438
|
+
let vectorStoreId;
|
|
11439
|
+
// If knowledge sources are provided, create a vector store with them
|
|
11440
|
+
if (knowledgeSources && knowledgeSources.length > 0) {
|
|
11441
|
+
const vectorStoreResult = await this.createVectorStoreWithKnowledgeSources({
|
|
11442
|
+
client,
|
|
11443
|
+
name: name !== null && name !== void 0 ? name : assistantId,
|
|
11444
|
+
knowledgeSources,
|
|
11445
|
+
logLabel: 'assistant update',
|
|
11446
|
+
});
|
|
11447
|
+
vectorStoreId = vectorStoreResult.vectorStoreId;
|
|
10869
11448
|
}
|
|
10870
11449
|
const assistantUpdate = {
|
|
10871
11450
|
name,
|
|
@@ -10908,7 +11487,7 @@ class OpenAiAssistantExecutionTools extends OpenAiExecutionTools {
|
|
|
10908
11487
|
* Discriminant for type guards
|
|
10909
11488
|
*/
|
|
10910
11489
|
get discriminant() {
|
|
10911
|
-
return DISCRIMINANT;
|
|
11490
|
+
return DISCRIMINANT$1;
|
|
10912
11491
|
}
|
|
10913
11492
|
/**
|
|
10914
11493
|
* Type guard to check if given `LlmExecutionTools` are instanceof `OpenAiAssistantExecutionTools`
|
|
@@ -10916,7 +11495,7 @@ class OpenAiAssistantExecutionTools extends OpenAiExecutionTools {
|
|
|
10916
11495
|
* Note: This is useful when you can possibly have multiple versions of `@promptbook/openai` installed
|
|
10917
11496
|
*/
|
|
10918
11497
|
static isOpenAiAssistantExecutionTools(llmExecutionTools) {
|
|
10919
|
-
return llmExecutionTools.discriminant === DISCRIMINANT;
|
|
11498
|
+
return llmExecutionTools.discriminant === DISCRIMINANT$1;
|
|
10920
11499
|
}
|
|
10921
11500
|
}
|
|
10922
11501
|
/**
|
|
@@ -10924,7 +11503,7 @@ class OpenAiAssistantExecutionTools extends OpenAiExecutionTools {
|
|
|
10924
11503
|
*
|
|
10925
11504
|
* @private const of `OpenAiAssistantExecutionTools`
|
|
10926
11505
|
*/
|
|
10927
|
-
const DISCRIMINANT = 'OPEN_AI_ASSISTANT_V1';
|
|
11506
|
+
const DISCRIMINANT$1 = 'OPEN_AI_ASSISTANT_V1';
|
|
10928
11507
|
/**
|
|
10929
11508
|
* TODO: !!!!! [✨🥚] Knowledge should work both with and without scrapers
|
|
10930
11509
|
* TODO: [🙎] In `OpenAiAssistantExecutionTools` Allow to create abstract assistants with `isCreatingNewAssistantsAllowed`
|
|
@@ -28926,206 +29505,425 @@ function promptbookifyAiText(text) {
|
|
|
28926
29505
|
* TODO: [🧠][✌️] Make some Promptbook-native token system
|
|
28927
29506
|
*/
|
|
28928
29507
|
|
|
29508
|
+
const DEFAULT_AGENT_KIT_MODEL_NAME = 'gpt-5.2';
|
|
28929
29509
|
/**
|
|
28930
|
-
* Execution
|
|
29510
|
+
* Execution tools for OpenAI AgentKit (Agents SDK).
|
|
28931
29511
|
*
|
|
28932
29512
|
* @public exported from `@promptbook/openai`
|
|
28933
29513
|
*/
|
|
28934
|
-
class
|
|
29514
|
+
class OpenAiAgentKitExecutionTools extends OpenAiVectorStoreHandler {
|
|
29515
|
+
/**
|
|
29516
|
+
* Creates OpenAI AgentKit execution tools.
|
|
29517
|
+
*/
|
|
28935
29518
|
constructor(options) {
|
|
29519
|
+
var _a;
|
|
29520
|
+
if (options.isProxied) {
|
|
29521
|
+
throw new NotYetImplementedError(`Proxy mode is not yet implemented for OpenAI AgentKit`);
|
|
29522
|
+
}
|
|
28936
29523
|
super(options);
|
|
28937
|
-
this.
|
|
29524
|
+
this.preparedAgentKitAgent = null;
|
|
29525
|
+
this.agentKitModelName = (_a = options.agentKitModelName) !== null && _a !== void 0 ? _a : DEFAULT_AGENT_KIT_MODEL_NAME;
|
|
28938
29526
|
}
|
|
28939
29527
|
get title() {
|
|
28940
|
-
return 'OpenAI
|
|
29528
|
+
return 'OpenAI AgentKit';
|
|
28941
29529
|
}
|
|
28942
29530
|
get description() {
|
|
28943
|
-
return 'Use OpenAI
|
|
29531
|
+
return 'Use OpenAI AgentKit for agent-style chat with tools and knowledge';
|
|
28944
29532
|
}
|
|
28945
29533
|
/**
|
|
28946
|
-
* Calls OpenAI
|
|
29534
|
+
* Calls OpenAI AgentKit with a chat prompt (non-streaming).
|
|
29535
|
+
*/
|
|
29536
|
+
async callChatModel(prompt) {
|
|
29537
|
+
return this.callChatModelStream(prompt, () => { });
|
|
29538
|
+
}
|
|
29539
|
+
/**
|
|
29540
|
+
* Calls OpenAI AgentKit with a chat prompt (streaming).
|
|
28947
29541
|
*/
|
|
28948
29542
|
async callChatModelStream(prompt, onProgress) {
|
|
28949
|
-
if (this.options.isVerbose) {
|
|
28950
|
-
console.info('💬 OpenAI Agent callChatModel call', { prompt });
|
|
28951
|
-
}
|
|
28952
29543
|
const { content, parameters, modelRequirements } = prompt;
|
|
28953
|
-
const client = await this.getClient();
|
|
28954
29544
|
if (modelRequirements.modelVariant !== 'CHAT') {
|
|
28955
29545
|
throw new PipelineExecutionError('Use callChatModel only for CHAT variant');
|
|
28956
29546
|
}
|
|
29547
|
+
for (const key of ['maxTokens', 'modelName', 'seed', 'temperature']) {
|
|
29548
|
+
if (modelRequirements[key] !== undefined) {
|
|
29549
|
+
throw new NotYetImplementedError(`In \`OpenAiAgentKitExecutionTools\` you cannot specify \`${key}\``);
|
|
29550
|
+
}
|
|
29551
|
+
}
|
|
28957
29552
|
const rawPromptContent = templateParameters(content, {
|
|
28958
29553
|
...parameters,
|
|
28959
|
-
modelName:
|
|
29554
|
+
modelName: this.agentKitModelName,
|
|
28960
29555
|
});
|
|
28961
|
-
|
|
28962
|
-
|
|
28963
|
-
|
|
28964
|
-
|
|
28965
|
-
|
|
28966
|
-
role: msg.sender === 'assistant' ? 'assistant' : 'user',
|
|
28967
|
-
content: msg.content,
|
|
28968
|
-
}));
|
|
28969
|
-
input.push(...previousMessages);
|
|
28970
|
-
}
|
|
28971
|
-
// Add current user message
|
|
28972
|
-
input.push({
|
|
28973
|
-
role: 'user',
|
|
28974
|
-
content: rawPromptContent,
|
|
29556
|
+
const preparedAgentKitAgent = await this.prepareAgentKitAgent({
|
|
29557
|
+
name: (prompt.title || 'Agent'),
|
|
29558
|
+
instructions: modelRequirements.systemMessage || '',
|
|
29559
|
+
knowledgeSources: modelRequirements.knowledgeSources,
|
|
29560
|
+
tools: 'tools' in prompt && Array.isArray(prompt.tools) ? prompt.tools : modelRequirements.tools,
|
|
28975
29561
|
});
|
|
28976
|
-
|
|
28977
|
-
|
|
28978
|
-
|
|
28979
|
-
|
|
28980
|
-
|
|
28981
|
-
|
|
28982
|
-
|
|
28983
|
-
|
|
28984
|
-
|
|
28985
|
-
|
|
28986
|
-
|
|
28987
|
-
|
|
29562
|
+
return this.callChatModelStreamWithPreparedAgent({
|
|
29563
|
+
openAiAgentKitAgent: preparedAgentKitAgent.agent,
|
|
29564
|
+
prompt,
|
|
29565
|
+
rawPromptContent,
|
|
29566
|
+
onProgress,
|
|
29567
|
+
});
|
|
29568
|
+
}
|
|
29569
|
+
/**
|
|
29570
|
+
* Returns a prepared AgentKit agent when the server wants to manage caching externally.
|
|
29571
|
+
*/
|
|
29572
|
+
getPreparedAgentKitAgent() {
|
|
29573
|
+
return this.preparedAgentKitAgent;
|
|
29574
|
+
}
|
|
29575
|
+
/**
|
|
29576
|
+
* Stores a prepared AgentKit agent for later reuse by external cache managers.
|
|
29577
|
+
*/
|
|
29578
|
+
setPreparedAgentKitAgent(preparedAgent) {
|
|
29579
|
+
this.preparedAgentKitAgent = preparedAgent;
|
|
29580
|
+
}
|
|
29581
|
+
/**
|
|
29582
|
+
* Creates a new tools instance bound to a prepared AgentKit agent.
|
|
29583
|
+
*/
|
|
29584
|
+
getPreparedAgentTools(preparedAgent) {
|
|
29585
|
+
const tools = new OpenAiAgentKitExecutionTools(this.agentKitOptions);
|
|
29586
|
+
tools.setPreparedAgentKitAgent(preparedAgent);
|
|
29587
|
+
return tools;
|
|
29588
|
+
}
|
|
29589
|
+
/**
|
|
29590
|
+
* Prepares an AgentKit agent with optional knowledge sources and tool definitions.
|
|
29591
|
+
*/
|
|
29592
|
+
async prepareAgentKitAgent(options) {
|
|
29593
|
+
var _a, _b;
|
|
29594
|
+
const { name, instructions, knowledgeSources, tools, vectorStoreId: cachedVectorStoreId, storeAsPrepared, } = options;
|
|
29595
|
+
await this.ensureAgentKitDefaults();
|
|
29596
|
+
if (this.options.isVerbose) {
|
|
29597
|
+
console.info('[🤰]', 'Preparing OpenAI AgentKit agent', {
|
|
29598
|
+
name,
|
|
29599
|
+
instructionsLength: instructions.length,
|
|
29600
|
+
knowledgeSourcesCount: (_a = knowledgeSources === null || knowledgeSources === void 0 ? void 0 : knowledgeSources.length) !== null && _a !== void 0 ? _a : 0,
|
|
29601
|
+
toolsCount: (_b = tools === null || tools === void 0 ? void 0 : tools.length) !== null && _b !== void 0 ? _b : 0,
|
|
29602
|
+
});
|
|
28988
29603
|
}
|
|
28989
|
-
|
|
28990
|
-
if (
|
|
28991
|
-
|
|
28992
|
-
|
|
28993
|
-
|
|
28994
|
-
|
|
28995
|
-
|
|
28996
|
-
|
|
29604
|
+
let vectorStoreId = cachedVectorStoreId;
|
|
29605
|
+
if (!vectorStoreId && knowledgeSources && knowledgeSources.length > 0) {
|
|
29606
|
+
const vectorStoreResult = await this.createVectorStoreWithKnowledgeSources({
|
|
29607
|
+
client: await this.getClient(),
|
|
29608
|
+
name,
|
|
29609
|
+
knowledgeSources,
|
|
29610
|
+
logLabel: 'agentkit preparation',
|
|
29611
|
+
});
|
|
29612
|
+
vectorStoreId = vectorStoreResult.vectorStoreId;
|
|
28997
29613
|
}
|
|
28998
|
-
|
|
28999
|
-
|
|
29000
|
-
|
|
29001
|
-
|
|
29002
|
-
|
|
29003
|
-
|
|
29004
|
-
|
|
29005
|
-
|
|
29006
|
-
|
|
29007
|
-
|
|
29614
|
+
else if (vectorStoreId && this.options.isVerbose) {
|
|
29615
|
+
console.info('[🤰]', 'Using cached vector store for AgentKit agent', {
|
|
29616
|
+
name,
|
|
29617
|
+
vectorStoreId,
|
|
29618
|
+
});
|
|
29619
|
+
}
|
|
29620
|
+
const agentKitTools = this.buildAgentKitTools({ tools, vectorStoreId });
|
|
29621
|
+
const openAiAgentKitAgent = new Agent$1({
|
|
29622
|
+
name,
|
|
29623
|
+
model: this.agentKitModelName,
|
|
29624
|
+
instructions: instructions || 'You are a helpful assistant.',
|
|
29625
|
+
tools: agentKitTools,
|
|
29626
|
+
});
|
|
29627
|
+
const preparedAgent = {
|
|
29628
|
+
agent: openAiAgentKitAgent,
|
|
29629
|
+
vectorStoreId,
|
|
29008
29630
|
};
|
|
29009
|
-
if (
|
|
29010
|
-
|
|
29631
|
+
if (storeAsPrepared) {
|
|
29632
|
+
this.setPreparedAgentKitAgent(preparedAgent);
|
|
29011
29633
|
}
|
|
29012
|
-
// Call Responses API
|
|
29013
|
-
// Note: Using any cast because types might not be updated yet
|
|
29014
|
-
const response = await client.responses.create(rawRequest);
|
|
29015
29634
|
if (this.options.isVerbose) {
|
|
29016
|
-
console.info(
|
|
29635
|
+
console.info('[🤰]', 'OpenAI AgentKit agent ready', {
|
|
29636
|
+
name,
|
|
29637
|
+
model: this.agentKitModelName,
|
|
29638
|
+
toolCount: agentKitTools.length,
|
|
29639
|
+
hasVectorStore: Boolean(vectorStoreId),
|
|
29640
|
+
});
|
|
29017
29641
|
}
|
|
29018
|
-
|
|
29019
|
-
|
|
29020
|
-
|
|
29021
|
-
|
|
29022
|
-
|
|
29023
|
-
|
|
29024
|
-
|
|
29025
|
-
|
|
29026
|
-
|
|
29027
|
-
|
|
29028
|
-
|
|
29642
|
+
return preparedAgent;
|
|
29643
|
+
}
|
|
29644
|
+
/**
|
|
29645
|
+
* Ensures the AgentKit SDK is wired to the OpenAI client and API key.
|
|
29646
|
+
*/
|
|
29647
|
+
async ensureAgentKitDefaults() {
|
|
29648
|
+
const client = await this.getClient();
|
|
29649
|
+
setDefaultOpenAIClient(client);
|
|
29650
|
+
const apiKey = this.agentKitOptions.apiKey;
|
|
29651
|
+
if (apiKey && typeof apiKey === 'string') {
|
|
29652
|
+
setDefaultOpenAIKey(apiKey);
|
|
29653
|
+
}
|
|
29654
|
+
}
|
|
29655
|
+
/**
|
|
29656
|
+
* Builds the tool list for AgentKit, including hosted file search when applicable.
|
|
29657
|
+
*/
|
|
29658
|
+
buildAgentKitTools(options) {
|
|
29659
|
+
var _a;
|
|
29660
|
+
const { tools, vectorStoreId } = options;
|
|
29661
|
+
const agentKitTools = [];
|
|
29662
|
+
if (vectorStoreId) {
|
|
29663
|
+
agentKitTools.push(fileSearchTool(vectorStoreId));
|
|
29664
|
+
}
|
|
29665
|
+
if (tools && tools.length > 0) {
|
|
29666
|
+
const scriptTools = this.resolveScriptTools();
|
|
29667
|
+
for (const toolDefinition of tools) {
|
|
29668
|
+
agentKitTools.push(tool({
|
|
29669
|
+
name: toolDefinition.name,
|
|
29670
|
+
description: toolDefinition.description,
|
|
29671
|
+
parameters: toolDefinition.parameters
|
|
29672
|
+
? {
|
|
29673
|
+
...toolDefinition.parameters,
|
|
29674
|
+
additionalProperties: false,
|
|
29675
|
+
required: (_a = toolDefinition.parameters.required) !== null && _a !== void 0 ? _a : [],
|
|
29676
|
+
}
|
|
29677
|
+
: undefined,
|
|
29678
|
+
strict: false,
|
|
29679
|
+
execute: async (input, runContext, details) => {
|
|
29680
|
+
var _a, _b, _c;
|
|
29681
|
+
const scriptTool = scriptTools[0];
|
|
29682
|
+
const functionName = toolDefinition.name;
|
|
29683
|
+
const calledAt = $getCurrentDate();
|
|
29684
|
+
const callId = (_a = details === null || details === void 0 ? void 0 : details.toolCall) === null || _a === void 0 ? void 0 : _a.callId;
|
|
29685
|
+
const functionArgs = input !== null && input !== void 0 ? input : {};
|
|
29686
|
+
if (this.options.isVerbose) {
|
|
29687
|
+
console.info('[🤰]', 'Executing AgentKit tool', {
|
|
29688
|
+
functionName,
|
|
29689
|
+
callId,
|
|
29690
|
+
calledAt,
|
|
29691
|
+
});
|
|
29692
|
+
}
|
|
29693
|
+
try {
|
|
29694
|
+
return await scriptTool.execute({
|
|
29695
|
+
scriptLanguage: 'javascript',
|
|
29696
|
+
script: `
|
|
29697
|
+
const args = ${JSON.stringify(functionArgs)};
|
|
29698
|
+
return await ${functionName}(args);
|
|
29699
|
+
`,
|
|
29700
|
+
parameters: (_c = (_b = runContext === null || runContext === void 0 ? void 0 : runContext.context) === null || _b === void 0 ? void 0 : _b.parameters) !== null && _c !== void 0 ? _c : {},
|
|
29701
|
+
});
|
|
29029
29702
|
}
|
|
29030
|
-
|
|
29031
|
-
|
|
29703
|
+
catch (error) {
|
|
29704
|
+
assertsError(error);
|
|
29705
|
+
const serializedError = serializeError(error);
|
|
29706
|
+
const errorMessage = spaceTrim$2((block) => `
|
|
29707
|
+
|
|
29708
|
+
The invoked tool \`${functionName}\` failed with error:
|
|
29709
|
+
|
|
29710
|
+
\`\`\`json
|
|
29711
|
+
${block(JSON.stringify(serializedError, null, 4))}
|
|
29712
|
+
\`\`\`
|
|
29713
|
+
|
|
29714
|
+
`);
|
|
29715
|
+
console.error('[🤰]', 'AgentKit tool execution failed', {
|
|
29716
|
+
functionName,
|
|
29717
|
+
callId,
|
|
29718
|
+
error: serializedError,
|
|
29719
|
+
});
|
|
29720
|
+
return errorMessage;
|
|
29032
29721
|
}
|
|
29722
|
+
},
|
|
29723
|
+
}));
|
|
29724
|
+
}
|
|
29725
|
+
}
|
|
29726
|
+
return agentKitTools;
|
|
29727
|
+
}
|
|
29728
|
+
/**
|
|
29729
|
+
* Resolves the configured script tools for tool execution.
|
|
29730
|
+
*/
|
|
29731
|
+
resolveScriptTools() {
|
|
29732
|
+
const executionTools = this.options.executionTools;
|
|
29733
|
+
if (!executionTools || !executionTools.script) {
|
|
29734
|
+
throw new PipelineExecutionError(`Model requested tools but no executionTools.script were provided in OpenAiAgentKitExecutionTools options`);
|
|
29735
|
+
}
|
|
29736
|
+
return Array.isArray(executionTools.script) ? executionTools.script : [executionTools.script];
|
|
29737
|
+
}
|
|
29738
|
+
/**
|
|
29739
|
+
* Runs a prepared AgentKit agent and streams results back to the caller.
|
|
29740
|
+
*/
|
|
29741
|
+
async callChatModelStreamWithPreparedAgent(options) {
|
|
29742
|
+
var _a, _b, _c, _d;
|
|
29743
|
+
const { openAiAgentKitAgent, prompt, onProgress } = options;
|
|
29744
|
+
const rawPromptContent = (_a = options.rawPromptContent) !== null && _a !== void 0 ? _a : templateParameters(prompt.content, {
|
|
29745
|
+
...prompt.parameters,
|
|
29746
|
+
modelName: this.agentKitModelName,
|
|
29747
|
+
});
|
|
29748
|
+
const start = $getCurrentDate();
|
|
29749
|
+
let latestContent = '';
|
|
29750
|
+
const toolCalls = [];
|
|
29751
|
+
const toolCallIndexById = new Map();
|
|
29752
|
+
const inputItems = await this.buildAgentKitInputItems(prompt, rawPromptContent);
|
|
29753
|
+
const rawRequest = {
|
|
29754
|
+
agentName: openAiAgentKitAgent.name,
|
|
29755
|
+
input: inputItems,
|
|
29756
|
+
};
|
|
29757
|
+
const streamResult = await run(openAiAgentKitAgent, inputItems, {
|
|
29758
|
+
stream: true,
|
|
29759
|
+
context: { parameters: prompt.parameters },
|
|
29760
|
+
});
|
|
29761
|
+
for await (const event of streamResult) {
|
|
29762
|
+
if (event.type === 'raw_model_stream_event' && ((_b = event.data) === null || _b === void 0 ? void 0 : _b.type) === 'output_text_delta') {
|
|
29763
|
+
latestContent += event.data.delta;
|
|
29764
|
+
onProgress({
|
|
29765
|
+
content: latestContent,
|
|
29766
|
+
modelName: this.agentKitModelName,
|
|
29767
|
+
timing: { start, complete: $getCurrentDate() },
|
|
29768
|
+
usage: UNCERTAIN_USAGE,
|
|
29769
|
+
rawPromptContent: rawPromptContent,
|
|
29770
|
+
rawRequest: null,
|
|
29771
|
+
rawResponse: {},
|
|
29772
|
+
});
|
|
29773
|
+
continue;
|
|
29774
|
+
}
|
|
29775
|
+
if (event.type === 'run_item_stream_event') {
|
|
29776
|
+
const rawItem = (_c = event.item) === null || _c === void 0 ? void 0 : _c.rawItem;
|
|
29777
|
+
if (event.name === 'tool_called' && (rawItem === null || rawItem === void 0 ? void 0 : rawItem.type) === 'function_call') {
|
|
29778
|
+
const toolCall = {
|
|
29779
|
+
name: rawItem.name,
|
|
29780
|
+
arguments: rawItem.arguments,
|
|
29781
|
+
rawToolCall: rawItem,
|
|
29782
|
+
createdAt: $getCurrentDate(),
|
|
29783
|
+
};
|
|
29784
|
+
toolCallIndexById.set(rawItem.callId, toolCalls.length);
|
|
29785
|
+
toolCalls.push(toolCall);
|
|
29786
|
+
onProgress({
|
|
29787
|
+
content: latestContent,
|
|
29788
|
+
modelName: this.agentKitModelName,
|
|
29789
|
+
timing: { start, complete: $getCurrentDate() },
|
|
29790
|
+
usage: UNCERTAIN_USAGE,
|
|
29791
|
+
rawPromptContent: rawPromptContent,
|
|
29792
|
+
rawRequest: null,
|
|
29793
|
+
rawResponse: {},
|
|
29794
|
+
toolCalls: [toolCall],
|
|
29795
|
+
});
|
|
29796
|
+
}
|
|
29797
|
+
if (event.name === 'tool_output' && (rawItem === null || rawItem === void 0 ? void 0 : rawItem.type) === 'function_call_result') {
|
|
29798
|
+
const index = toolCallIndexById.get(rawItem.callId);
|
|
29799
|
+
const result = this.formatAgentKitToolOutput(rawItem.output);
|
|
29800
|
+
if (index !== undefined) {
|
|
29801
|
+
const existingToolCall = toolCalls[index];
|
|
29802
|
+
const completedToolCall = {
|
|
29803
|
+
...existingToolCall,
|
|
29804
|
+
result,
|
|
29805
|
+
rawToolCall: rawItem,
|
|
29806
|
+
};
|
|
29807
|
+
toolCalls[index] = completedToolCall;
|
|
29808
|
+
onProgress({
|
|
29809
|
+
content: latestContent,
|
|
29810
|
+
modelName: this.agentKitModelName,
|
|
29811
|
+
timing: { start, complete: $getCurrentDate() },
|
|
29812
|
+
usage: UNCERTAIN_USAGE,
|
|
29813
|
+
rawPromptContent: rawPromptContent,
|
|
29814
|
+
rawRequest: null,
|
|
29815
|
+
rawResponse: {},
|
|
29816
|
+
toolCalls: [completedToolCall],
|
|
29817
|
+
});
|
|
29033
29818
|
}
|
|
29034
29819
|
}
|
|
29035
|
-
else if (item.type === 'function_call') ;
|
|
29036
29820
|
}
|
|
29037
29821
|
}
|
|
29038
|
-
|
|
29039
|
-
|
|
29040
|
-
|
|
29041
|
-
|
|
29042
|
-
|
|
29043
|
-
|
|
29044
|
-
content: resultContent,
|
|
29045
|
-
modelName: response.model || 'agent',
|
|
29822
|
+
await streamResult.completed;
|
|
29823
|
+
const complete = $getCurrentDate();
|
|
29824
|
+
const finalContent = ((_d = streamResult.finalOutput) !== null && _d !== void 0 ? _d : latestContent);
|
|
29825
|
+
const finalResult = {
|
|
29826
|
+
content: finalContent,
|
|
29827
|
+
modelName: this.agentKitModelName,
|
|
29046
29828
|
timing: { start, complete },
|
|
29047
29829
|
usage: UNCERTAIN_USAGE,
|
|
29048
|
-
rawPromptContent,
|
|
29830
|
+
rawPromptContent: rawPromptContent,
|
|
29049
29831
|
rawRequest,
|
|
29050
|
-
rawResponse:
|
|
29051
|
-
|
|
29052
|
-
|
|
29053
|
-
|
|
29054
|
-
|
|
29055
|
-
order: [],
|
|
29056
|
-
value: {
|
|
29057
|
-
content: resultContent,
|
|
29058
|
-
modelName: response.model || 'agent',
|
|
29059
|
-
timing: { start, complete },
|
|
29060
|
-
usage: UNCERTAIN_USAGE,
|
|
29061
|
-
rawPromptContent,
|
|
29062
|
-
rawRequest,
|
|
29063
|
-
rawResponse: response,
|
|
29064
|
-
toolCalls: toolCalls.length > 0 ? toolCalls : undefined,
|
|
29065
|
-
},
|
|
29066
|
-
});
|
|
29832
|
+
rawResponse: { runResult: streamResult },
|
|
29833
|
+
toolCalls: toolCalls.length > 0 ? toolCalls : undefined,
|
|
29834
|
+
};
|
|
29835
|
+
onProgress(finalResult);
|
|
29836
|
+
return finalResult;
|
|
29067
29837
|
}
|
|
29068
29838
|
/**
|
|
29069
|
-
*
|
|
29839
|
+
* Builds AgentKit input items from the prompt and optional thread.
|
|
29070
29840
|
*/
|
|
29071
|
-
|
|
29072
|
-
|
|
29073
|
-
const
|
|
29074
|
-
|
|
29075
|
-
|
|
29076
|
-
|
|
29077
|
-
|
|
29078
|
-
|
|
29079
|
-
|
|
29080
|
-
|
|
29081
|
-
|
|
29082
|
-
|
|
29083
|
-
|
|
29084
|
-
const response = await fetch(source);
|
|
29085
|
-
if (!response.ok) {
|
|
29086
|
-
console.error(`Failed to download ${source}: ${response.statusText}`);
|
|
29087
|
-
continue;
|
|
29088
|
-
}
|
|
29089
|
-
const buffer = await response.arrayBuffer();
|
|
29090
|
-
const filename = source.split('/').pop() || 'downloaded-file';
|
|
29091
|
-
const blob = new Blob([buffer]);
|
|
29092
|
-
const file = new File([blob], filename);
|
|
29093
|
-
fileStreams.push(file);
|
|
29841
|
+
async buildAgentKitInputItems(prompt, rawPromptContent) {
|
|
29842
|
+
var _a;
|
|
29843
|
+
const inputItems = [];
|
|
29844
|
+
if ('thread' in prompt && Array.isArray(prompt.thread)) {
|
|
29845
|
+
for (const message of prompt.thread) {
|
|
29846
|
+
const sender = message.sender;
|
|
29847
|
+
const content = (_a = message.content) !== null && _a !== void 0 ? _a : '';
|
|
29848
|
+
if (sender === 'assistant' || sender === 'agent') {
|
|
29849
|
+
inputItems.push({
|
|
29850
|
+
role: 'assistant',
|
|
29851
|
+
status: 'completed',
|
|
29852
|
+
content: [{ type: 'output_text', text: content }],
|
|
29853
|
+
});
|
|
29094
29854
|
}
|
|
29095
29855
|
else {
|
|
29096
|
-
|
|
29856
|
+
inputItems.push({
|
|
29857
|
+
role: 'user',
|
|
29858
|
+
content,
|
|
29859
|
+
});
|
|
29097
29860
|
}
|
|
29098
29861
|
}
|
|
29099
|
-
catch (error) {
|
|
29100
|
-
console.error(`Error processing knowledge source ${source}:`, error);
|
|
29101
|
-
}
|
|
29102
29862
|
}
|
|
29103
|
-
|
|
29104
|
-
|
|
29105
|
-
|
|
29106
|
-
|
|
29107
|
-
|
|
29108
|
-
|
|
29109
|
-
|
|
29110
|
-
|
|
29111
|
-
|
|
29863
|
+
const userContent = await this.buildAgentKitUserContent(prompt, rawPromptContent);
|
|
29864
|
+
inputItems.push({
|
|
29865
|
+
role: 'user',
|
|
29866
|
+
content: userContent,
|
|
29867
|
+
});
|
|
29868
|
+
return inputItems;
|
|
29869
|
+
}
|
|
29870
|
+
/**
|
|
29871
|
+
* Builds the user message content for AgentKit runs, including file inputs when provided.
|
|
29872
|
+
*/
|
|
29873
|
+
async buildAgentKitUserContent(prompt, rawPromptContent) {
|
|
29874
|
+
if ('files' in prompt && Array.isArray(prompt.files) && prompt.files.length > 0) {
|
|
29875
|
+
const fileItems = await Promise.all(prompt.files.map(async (file) => {
|
|
29876
|
+
const arrayBuffer = await file.arrayBuffer();
|
|
29877
|
+
const base64 = Buffer.from(arrayBuffer).toString('base64');
|
|
29878
|
+
return {
|
|
29879
|
+
type: 'input_image',
|
|
29880
|
+
image: `data:${file.type};base64,${base64}`,
|
|
29881
|
+
};
|
|
29882
|
+
}));
|
|
29883
|
+
return [{ type: 'input_text', text: rawPromptContent }, ...fileItems];
|
|
29884
|
+
}
|
|
29885
|
+
return rawPromptContent;
|
|
29886
|
+
}
|
|
29887
|
+
/**
|
|
29888
|
+
* Normalizes AgentKit tool outputs into a string for Promptbook tool call results.
|
|
29889
|
+
*/
|
|
29890
|
+
formatAgentKitToolOutput(output) {
|
|
29891
|
+
if (typeof output === 'string') {
|
|
29892
|
+
return output;
|
|
29893
|
+
}
|
|
29894
|
+
if (output && typeof output === 'object') {
|
|
29895
|
+
const textOutput = output;
|
|
29896
|
+
if (textOutput.type === 'text' && typeof textOutput.text === 'string') {
|
|
29897
|
+
return textOutput.text;
|
|
29112
29898
|
}
|
|
29113
29899
|
}
|
|
29114
|
-
return
|
|
29900
|
+
return JSON.stringify(output !== null && output !== void 0 ? output : null);
|
|
29115
29901
|
}
|
|
29116
29902
|
/**
|
|
29117
|
-
*
|
|
29903
|
+
* Returns AgentKit-specific options.
|
|
29904
|
+
*/
|
|
29905
|
+
get agentKitOptions() {
|
|
29906
|
+
return this.options;
|
|
29907
|
+
}
|
|
29908
|
+
/**
|
|
29909
|
+
* Discriminant for type guards.
|
|
29118
29910
|
*/
|
|
29119
29911
|
get discriminant() {
|
|
29120
|
-
return
|
|
29912
|
+
return DISCRIMINANT;
|
|
29121
29913
|
}
|
|
29122
29914
|
/**
|
|
29123
|
-
* Type guard to check if given `LlmExecutionTools` are instanceof `
|
|
29915
|
+
* Type guard to check if given `LlmExecutionTools` are instanceof `OpenAiAgentKitExecutionTools`.
|
|
29124
29916
|
*/
|
|
29125
|
-
static
|
|
29126
|
-
return llmExecutionTools.discriminant ===
|
|
29917
|
+
static isOpenAiAgentKitExecutionTools(llmExecutionTools) {
|
|
29918
|
+
return llmExecutionTools.discriminant === DISCRIMINANT;
|
|
29127
29919
|
}
|
|
29128
29920
|
}
|
|
29921
|
+
/**
|
|
29922
|
+
* Discriminant for type guards.
|
|
29923
|
+
*
|
|
29924
|
+
* @private const of `OpenAiAgentKitExecutionTools`
|
|
29925
|
+
*/
|
|
29926
|
+
const DISCRIMINANT = 'OPEN_AI_AGENT_KIT_V1';
|
|
29129
29927
|
|
|
29130
29928
|
/**
|
|
29131
29929
|
* Emits a progress update to signal assistant preparation before long setup work.
|
|
@@ -29162,8 +29960,8 @@ function emitAssistantPreparationProgress(options) {
|
|
|
29162
29960
|
* - `Agent` - which represents an AI Agent with its source, memories, actions, etc. Agent is a higher-level abstraction which is internally using:
|
|
29163
29961
|
* - `LlmExecutionTools` - which wraps one or more LLM models and provides an interface to execute them
|
|
29164
29962
|
* - `AgentLlmExecutionTools` - which is a specific implementation of `LlmExecutionTools` that wraps another LlmExecutionTools and applies agent-specific system prompts and requirements
|
|
29165
|
-
* - `OpenAiAgentExecutionTools` - which is a specific implementation of `LlmExecutionTools` for OpenAI models with agent capabilities (using Responses API), recommended for usage in `Agent` or `AgentLlmExecutionTools`
|
|
29166
29963
|
* - `OpenAiAssistantExecutionTools` - (Deprecated) which is a specific implementation of `LlmExecutionTools` for OpenAI models with assistant capabilities
|
|
29964
|
+
* - `OpenAiAgentKitExecutionTools` - which is a specific implementation of `LlmExecutionTools` backed by OpenAI AgentKit
|
|
29167
29965
|
* - `RemoteAgent` - which is an `Agent` that connects to a Promptbook Agents Server
|
|
29168
29966
|
*
|
|
29169
29967
|
* @public exported from `@promptbook/core`
|
|
@@ -29298,6 +30096,7 @@ class AgentLlmExecutionTools {
|
|
|
29298
30096
|
* Calls the chat model with agent-specific system prompt and requirements with streaming
|
|
29299
30097
|
*/
|
|
29300
30098
|
async callChatModelStream(prompt, onProgress) {
|
|
30099
|
+
var _a, _b;
|
|
29301
30100
|
// Ensure we're working with a chat prompt
|
|
29302
30101
|
if (prompt.modelRequirements.modelVariant !== 'CHAT') {
|
|
29303
30102
|
throw new Error('AgentLlmExecutionTools only supports chat prompts');
|
|
@@ -29325,63 +30124,73 @@ class AgentLlmExecutionTools {
|
|
|
29325
30124
|
}, // Cast to avoid readonly mismatch from spread
|
|
29326
30125
|
};
|
|
29327
30126
|
console.log('!!!! promptWithAgentModelRequirements:', promptWithAgentModelRequirements);
|
|
29328
|
-
if (
|
|
30127
|
+
if (OpenAiAgentKitExecutionTools.isOpenAiAgentKitExecutionTools(this.options.llmTools)) {
|
|
29329
30128
|
const requirementsHash = SHA256(JSON.stringify(modelRequirements)).toString();
|
|
29330
|
-
const
|
|
29331
|
-
|
|
29332
|
-
|
|
30129
|
+
const vectorStoreHash = SHA256(JSON.stringify((_a = modelRequirements.knowledgeSources) !== null && _a !== void 0 ? _a : [])).toString();
|
|
30130
|
+
const cachedVectorStore = AgentLlmExecutionTools.vectorStoreCache.get(this.title);
|
|
30131
|
+
const cachedAgentKit = AgentLlmExecutionTools.agentKitAgentCache.get(this.title);
|
|
30132
|
+
let preparedAgentKit = this.options.assistantPreparationMode === 'external'
|
|
30133
|
+
? this.options.llmTools.getPreparedAgentKitAgent()
|
|
30134
|
+
: null;
|
|
30135
|
+
const vectorStoreId = (preparedAgentKit === null || preparedAgentKit === void 0 ? void 0 : preparedAgentKit.vectorStoreId) ||
|
|
30136
|
+
(cachedVectorStore && cachedVectorStore.requirementsHash === vectorStoreHash
|
|
30137
|
+
? cachedVectorStore.vectorStoreId
|
|
30138
|
+
: undefined);
|
|
30139
|
+
if (!preparedAgentKit && cachedAgentKit && cachedAgentKit.requirementsHash === requirementsHash) {
|
|
29333
30140
|
if (this.options.isVerbose) {
|
|
29334
|
-
console.
|
|
30141
|
+
console.info('[🤰]', 'Using cached OpenAI AgentKit agent', {
|
|
30142
|
+
agent: this.title,
|
|
30143
|
+
});
|
|
29335
30144
|
}
|
|
29336
|
-
|
|
29337
|
-
|
|
29338
|
-
|
|
29339
|
-
|
|
29340
|
-
// We can cast to access options if they were public, or use a method to clone.
|
|
29341
|
-
// OpenAiAgentExecutionTools doesn't have a clone method.
|
|
29342
|
-
// However, we can just assume the passed tool *might* not have the vector store yet, or we are replacing it.
|
|
29343
|
-
// Actually, if the passed tool IS OpenAiAgentExecutionTools, we should use it as a base.
|
|
29344
|
-
// TODO: [🧠] This is a bit hacky, accessing protected options or recreating tools.
|
|
29345
|
-
// Ideally OpenAiAgentExecutionTools should have a method `withVectorStoreId`.
|
|
29346
|
-
agentTools = new OpenAiAgentExecutionTools({
|
|
29347
|
-
...this.options.llmTools.options,
|
|
29348
|
-
vectorStoreId: cached.vectorStoreId,
|
|
29349
|
-
});
|
|
30145
|
+
preparedAgentKit = {
|
|
30146
|
+
agent: cachedAgentKit.agent,
|
|
30147
|
+
vectorStoreId: cachedAgentKit.vectorStoreId,
|
|
30148
|
+
};
|
|
29350
30149
|
}
|
|
29351
|
-
|
|
30150
|
+
if (!preparedAgentKit) {
|
|
29352
30151
|
if (this.options.isVerbose) {
|
|
29353
|
-
console.
|
|
29354
|
-
|
|
29355
|
-
|
|
29356
|
-
if (modelRequirements.knowledgeSources && modelRequirements.knowledgeSources.length > 0) {
|
|
29357
|
-
const client = await this.options.llmTools.getClient();
|
|
29358
|
-
vectorStoreId = await OpenAiAgentExecutionTools.createVectorStore(client, this.title, modelRequirements.knowledgeSources);
|
|
30152
|
+
console.info('[🤰]', 'Preparing OpenAI AgentKit agent', {
|
|
30153
|
+
agent: this.title,
|
|
30154
|
+
});
|
|
29359
30155
|
}
|
|
29360
|
-
if (vectorStoreId) {
|
|
29361
|
-
|
|
29362
|
-
|
|
29363
|
-
|
|
30156
|
+
if (!vectorStoreId && ((_b = modelRequirements.knowledgeSources) === null || _b === void 0 ? void 0 : _b.length)) {
|
|
30157
|
+
emitAssistantPreparationProgress({
|
|
30158
|
+
onProgress,
|
|
30159
|
+
prompt,
|
|
30160
|
+
modelName: this.modelName,
|
|
30161
|
+
phase: 'Creating knowledge base',
|
|
29364
30162
|
});
|
|
29365
30163
|
}
|
|
29366
|
-
|
|
29367
|
-
|
|
30164
|
+
emitAssistantPreparationProgress({
|
|
30165
|
+
onProgress,
|
|
30166
|
+
prompt,
|
|
30167
|
+
modelName: this.modelName,
|
|
30168
|
+
phase: 'Preparing AgentKit agent',
|
|
30169
|
+
});
|
|
30170
|
+
preparedAgentKit = await this.options.llmTools.prepareAgentKitAgent({
|
|
30171
|
+
name: this.title,
|
|
30172
|
+
instructions: modelRequirements.systemMessage || '',
|
|
30173
|
+
knowledgeSources: modelRequirements.knowledgeSources,
|
|
30174
|
+
tools: modelRequirements.tools ? [...modelRequirements.tools] : undefined,
|
|
29368
30175
|
vectorStoreId,
|
|
29369
30176
|
});
|
|
29370
30177
|
}
|
|
29371
|
-
|
|
29372
|
-
|
|
29373
|
-
|
|
29374
|
-
|
|
29375
|
-
|
|
29376
|
-
|
|
29377
|
-
|
|
29378
|
-
|
|
29379
|
-
|
|
29380
|
-
|
|
29381
|
-
|
|
29382
|
-
|
|
29383
|
-
|
|
29384
|
-
|
|
30178
|
+
if (preparedAgentKit.vectorStoreId) {
|
|
30179
|
+
AgentLlmExecutionTools.vectorStoreCache.set(this.title, {
|
|
30180
|
+
vectorStoreId: preparedAgentKit.vectorStoreId,
|
|
30181
|
+
requirementsHash: vectorStoreHash,
|
|
30182
|
+
});
|
|
30183
|
+
}
|
|
30184
|
+
AgentLlmExecutionTools.agentKitAgentCache.set(this.title, {
|
|
30185
|
+
agent: preparedAgentKit.agent,
|
|
30186
|
+
requirementsHash,
|
|
30187
|
+
vectorStoreId: preparedAgentKit.vectorStoreId,
|
|
30188
|
+
});
|
|
30189
|
+
underlyingLlmResult = await this.options.llmTools.callChatModelStreamWithPreparedAgent({
|
|
30190
|
+
openAiAgentKitAgent: preparedAgentKit.agent,
|
|
30191
|
+
prompt: promptWithAgentModelRequirements,
|
|
30192
|
+
onProgress,
|
|
30193
|
+
});
|
|
29385
30194
|
}
|
|
29386
30195
|
else if (OpenAiAssistantExecutionTools.isOpenAiAssistantExecutionTools(this.options.llmTools)) {
|
|
29387
30196
|
// ... deprecated path ...
|
|
@@ -29508,6 +30317,10 @@ class AgentLlmExecutionTools {
|
|
|
29508
30317
|
return agentResult;
|
|
29509
30318
|
}
|
|
29510
30319
|
}
|
|
30320
|
+
/**
|
|
30321
|
+
* Cached AgentKit agents to avoid rebuilding identical instances.
|
|
30322
|
+
*/
|
|
30323
|
+
AgentLlmExecutionTools.agentKitAgentCache = new Map();
|
|
29511
30324
|
/**
|
|
29512
30325
|
* Cache of OpenAI assistants to avoid creating duplicates
|
|
29513
30326
|
*/
|
|
@@ -29588,8 +30401,8 @@ function buildTeacherSummary(commitments, used) {
|
|
|
29588
30401
|
* - `Agent` - which represents an AI Agent with its source, memories, actions, etc. Agent is a higher-level abstraction which is internally using:
|
|
29589
30402
|
* - `LlmExecutionTools` - which wraps one or more LLM models and provides an interface to execute them
|
|
29590
30403
|
* - `AgentLlmExecutionTools` - which is a specific implementation of `LlmExecutionTools` that wraps another LlmExecutionTools and applies agent-specific system prompts and requirements
|
|
29591
|
-
* - `OpenAiAgentExecutionTools` - which is a specific implementation of `LlmExecutionTools` for OpenAI models with agent capabilities (using Responses API), recommended for usage in `Agent` or `AgentLlmExecutionTools`
|
|
29592
30404
|
* - `OpenAiAssistantExecutionTools` - (Deprecated) which is a specific implementation of `LlmExecutionTools` for OpenAI models with assistant capabilities
|
|
30405
|
+
* - `OpenAiAgentKitExecutionTools` - which is a specific implementation of `LlmExecutionTools` backed by OpenAI AgentKit
|
|
29593
30406
|
* - `RemoteAgent` - which is an `Agent` that connects to a Promptbook Agents Server
|
|
29594
30407
|
*
|
|
29595
30408
|
* @public exported from `@promptbook/core`
|
|
@@ -29960,7 +30773,8 @@ function buildRemoteAgentSource(profile, meta) {
|
|
|
29960
30773
|
* - `Agent` - which represents an AI Agent with its source, memories, actions, etc. Agent is a higher-level abstraction which is internally using:
|
|
29961
30774
|
* - `LlmExecutionTools` - which wraps one or more LLM models and provides an interface to execute them
|
|
29962
30775
|
* - `AgentLlmExecutionTools` - which is a specific implementation of `LlmExecutionTools` that wraps another LlmExecutionTools and applies agent-specific system prompts and requirements
|
|
29963
|
-
* - `OpenAiAssistantExecutionTools` - which is a specific implementation of `LlmExecutionTools` for OpenAI models with assistant capabilities
|
|
30776
|
+
* - `OpenAiAssistantExecutionTools` - (Deprecated) which is a specific implementation of `LlmExecutionTools` for OpenAI models with assistant capabilities
|
|
30777
|
+
* - `OpenAiAgentKitExecutionTools` - which is a specific implementation of `LlmExecutionTools` backed by OpenAI AgentKit
|
|
29964
30778
|
* - `RemoteAgent` - which is an `Agent` that connects to a Promptbook Agents Server
|
|
29965
30779
|
*
|
|
29966
30780
|
* @public exported from `@promptbook/core`
|