@promptbook/node 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 +1226 -412
- 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 +1229 -416
- 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/umd/index.umd.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
(function (global, factory) {
|
|
2
|
-
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('colors'), require('fs/promises'), require('path'), require('spacetrim'), require('jszip'), require('crypto'), require('crypto-js'), require('crypto-js/enc-hex'), require('@mozilla/readability'), require('jsdom'), require('showdown'), require('child_process'), require('waitasecond'), require('dotenv'), require('crypto-js/sha256'), require('rxjs'), require('moment'), require('mime-types'), require('papaparse'), require('bottleneck'), require('openai')) :
|
|
3
|
-
typeof define === 'function' && define.amd ? define(['exports', 'colors', 'fs/promises', 'path', 'spacetrim', 'jszip', 'crypto', 'crypto-js', 'crypto-js/enc-hex', '@mozilla/readability', 'jsdom', 'showdown', 'child_process', 'waitasecond', 'dotenv', 'crypto-js/sha256', 'rxjs', 'moment', 'mime-types', 'papaparse', 'bottleneck', 'openai'], factory) :
|
|
4
|
-
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["promptbook-node"] = {}, global.colors, global.promises, global.path, global.spaceTrim$1, global.JSZip, global.crypto, global.cryptoJs, global.hexEncoder, global.readability, global.jsdom, global.showdown, global.child_process, global.waitasecond, global.dotenv, global.sha256, global.rxjs, global.moment, global.mimeTypes, global.papaparse, global.Bottleneck, global.OpenAI));
|
|
5
|
-
})(this, (function (exports, colors, promises, path, spaceTrim$1, JSZip, crypto, cryptoJs, hexEncoder, readability, jsdom, showdown, child_process, waitasecond, dotenv, sha256, rxjs, moment, mimeTypes, papaparse, Bottleneck, OpenAI) { 'use strict';
|
|
2
|
+
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('colors'), require('fs/promises'), require('path'), require('spacetrim'), require('jszip'), require('crypto'), require('crypto-js'), require('crypto-js/enc-hex'), require('@mozilla/readability'), require('jsdom'), require('showdown'), require('child_process'), require('waitasecond'), require('dotenv'), require('crypto-js/sha256'), require('rxjs'), require('moment'), require('mime-types'), require('papaparse'), require('@openai/agents'), require('bottleneck'), require('openai')) :
|
|
3
|
+
typeof define === 'function' && define.amd ? define(['exports', 'colors', 'fs/promises', 'path', 'spacetrim', 'jszip', 'crypto', 'crypto-js', 'crypto-js/enc-hex', '@mozilla/readability', 'jsdom', 'showdown', 'child_process', 'waitasecond', 'dotenv', 'crypto-js/sha256', 'rxjs', 'moment', 'mime-types', 'papaparse', '@openai/agents', 'bottleneck', 'openai'], factory) :
|
|
4
|
+
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["promptbook-node"] = {}, global.colors, global.promises, global.path, global.spaceTrim$1, global.JSZip, global.crypto, global.cryptoJs, global.hexEncoder, global.readability, global.jsdom, global.showdown, global.child_process, global.waitasecond, global.dotenv, global.sha256, global.rxjs, global.moment, global.mimeTypes, global.papaparse, global.agents, global.Bottleneck, global.OpenAI));
|
|
5
|
+
})(this, (function (exports, colors, promises, path, spaceTrim$1, JSZip, crypto, cryptoJs, hexEncoder, readability, jsdom, showdown, child_process, waitasecond, dotenv, sha256, rxjs, moment, mimeTypes, papaparse, agents, Bottleneck, OpenAI) { 'use strict';
|
|
6
6
|
|
|
7
7
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
8
8
|
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
* @generated
|
|
49
49
|
* @see https://github.com/webgptorg/promptbook
|
|
50
50
|
*/
|
|
51
|
-
const PROMPTBOOK_ENGINE_VERSION = '0.110.0-
|
|
51
|
+
const PROMPTBOOK_ENGINE_VERSION = '0.110.0-7';
|
|
52
52
|
/**
|
|
53
53
|
* TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
|
|
54
54
|
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
@@ -22372,16 +22372,11 @@
|
|
|
22372
22372
|
const openAiOptions = { ...this.options };
|
|
22373
22373
|
delete openAiOptions.isVerbose;
|
|
22374
22374
|
delete openAiOptions.userId;
|
|
22375
|
-
// Enhanced configuration
|
|
22375
|
+
// Enhanced configuration with retries and timeouts.
|
|
22376
22376
|
const enhancedOptions = {
|
|
22377
22377
|
...openAiOptions,
|
|
22378
22378
|
timeout: API_REQUEST_TIMEOUT,
|
|
22379
22379
|
maxRetries: CONNECTION_RETRIES_LIMIT,
|
|
22380
|
-
defaultHeaders: {
|
|
22381
|
-
Connection: 'keep-alive',
|
|
22382
|
-
'Keep-Alive': 'timeout=30, max=100',
|
|
22383
|
-
...openAiOptions.defaultHeaders,
|
|
22384
|
-
},
|
|
22385
22380
|
};
|
|
22386
22381
|
this.client = new OpenAI__default["default"](enhancedOptions);
|
|
22387
22382
|
}
|
|
@@ -23270,18 +23265,6 @@
|
|
|
23270
23265
|
get profile() {
|
|
23271
23266
|
return OPENAI_PROVIDER_PROFILE;
|
|
23272
23267
|
}
|
|
23273
|
-
/*
|
|
23274
|
-
Note: Commenting this out to avoid circular dependency
|
|
23275
|
-
/**
|
|
23276
|
-
* Create (sub)tools for calling OpenAI API Assistants
|
|
23277
|
-
*
|
|
23278
|
-
* @param assistantId Which assistant to use
|
|
23279
|
-
* @returns Tools for calling OpenAI API Assistants with same token
|
|
23280
|
-
* /
|
|
23281
|
-
public createAssistantSubtools(assistantId: string_token): OpenAiAssistantExecutionTools {
|
|
23282
|
-
return new OpenAiAssistantExecutionTools({ ...this.options, assistantId });
|
|
23283
|
-
}
|
|
23284
|
-
*/
|
|
23285
23268
|
/**
|
|
23286
23269
|
* List all available models (non dynamically)
|
|
23287
23270
|
*
|
|
@@ -23309,213 +23292,1180 @@
|
|
|
23309
23292
|
return this.getDefaultModel('text-embedding-3-large');
|
|
23310
23293
|
}
|
|
23311
23294
|
/**
|
|
23312
|
-
* Default model for image generation variant.
|
|
23295
|
+
* Default model for image generation variant.
|
|
23296
|
+
*/
|
|
23297
|
+
getDefaultImageGenerationModel() {
|
|
23298
|
+
return this.getDefaultModel('dall-e-3');
|
|
23299
|
+
}
|
|
23300
|
+
}
|
|
23301
|
+
|
|
23302
|
+
const DEFAULT_KNOWLEDGE_SOURCE_DOWNLOAD_TIMEOUT_MS = 30000;
|
|
23303
|
+
const DEFAULT_KNOWLEDGE_SOURCE_UPLOAD_TIMEOUT_MS = 900000;
|
|
23304
|
+
const VECTOR_STORE_PROGRESS_LOG_INTERVAL_MIN_MS = 15000;
|
|
23305
|
+
const VECTOR_STORE_STALL_LOG_THRESHOLD_MS = 30000;
|
|
23306
|
+
/**
|
|
23307
|
+
* Base class for OpenAI execution tools that need hosted vector stores.
|
|
23308
|
+
*
|
|
23309
|
+
* @public exported from `@promptbook/openai`
|
|
23310
|
+
*/
|
|
23311
|
+
class OpenAiVectorStoreHandler extends OpenAiExecutionTools {
|
|
23312
|
+
/**
|
|
23313
|
+
* Returns the per-knowledge-source download timeout in milliseconds.
|
|
23314
|
+
*/
|
|
23315
|
+
getKnowledgeSourceDownloadTimeoutMs() {
|
|
23316
|
+
var _a;
|
|
23317
|
+
return (_a = this.vectorStoreOptions.knowledgeSourceDownloadTimeoutMs) !== null && _a !== void 0 ? _a : DEFAULT_KNOWLEDGE_SOURCE_DOWNLOAD_TIMEOUT_MS;
|
|
23318
|
+
}
|
|
23319
|
+
/**
|
|
23320
|
+
* Returns the max concurrency for knowledge source uploads.
|
|
23321
|
+
*/
|
|
23322
|
+
getKnowledgeSourceUploadMaxConcurrency() {
|
|
23323
|
+
var _a;
|
|
23324
|
+
return (_a = this.vectorStoreOptions.knowledgeSourceUploadMaxConcurrency) !== null && _a !== void 0 ? _a : 5;
|
|
23325
|
+
}
|
|
23326
|
+
/**
|
|
23327
|
+
* Returns the polling interval in milliseconds for vector store uploads.
|
|
23328
|
+
*/
|
|
23329
|
+
getKnowledgeSourceUploadPollIntervalMs() {
|
|
23330
|
+
var _a;
|
|
23331
|
+
return (_a = this.vectorStoreOptions.knowledgeSourceUploadPollIntervalMs) !== null && _a !== void 0 ? _a : 5000;
|
|
23332
|
+
}
|
|
23333
|
+
/**
|
|
23334
|
+
* Returns the overall upload timeout in milliseconds for vector store uploads.
|
|
23335
|
+
*/
|
|
23336
|
+
getKnowledgeSourceUploadTimeoutMs() {
|
|
23337
|
+
var _a;
|
|
23338
|
+
return (_a = this.vectorStoreOptions.knowledgeSourceUploadTimeoutMs) !== null && _a !== void 0 ? _a : DEFAULT_KNOWLEDGE_SOURCE_UPLOAD_TIMEOUT_MS;
|
|
23339
|
+
}
|
|
23340
|
+
/**
|
|
23341
|
+
* Returns true if we should continue even if vector store ingestion stalls.
|
|
23342
|
+
*/
|
|
23343
|
+
shouldContinueOnVectorStoreStall() {
|
|
23344
|
+
var _a;
|
|
23345
|
+
return (_a = this.vectorStoreOptions.shouldContinueOnVectorStoreStall) !== null && _a !== void 0 ? _a : true;
|
|
23346
|
+
}
|
|
23347
|
+
/**
|
|
23348
|
+
* Returns vector-store-specific options with extended settings.
|
|
23349
|
+
*/
|
|
23350
|
+
get vectorStoreOptions() {
|
|
23351
|
+
return this.options;
|
|
23352
|
+
}
|
|
23353
|
+
/**
|
|
23354
|
+
* Returns the OpenAI vector stores API surface, supporting stable and beta SDKs.
|
|
23355
|
+
*/
|
|
23356
|
+
getVectorStoresApi(client) {
|
|
23357
|
+
var _a, _b;
|
|
23358
|
+
const vectorStores = (_a = client.vectorStores) !== null && _a !== void 0 ? _a : (_b = client.beta) === null || _b === void 0 ? void 0 : _b.vectorStores;
|
|
23359
|
+
if (!vectorStores) {
|
|
23360
|
+
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.');
|
|
23361
|
+
}
|
|
23362
|
+
return vectorStores;
|
|
23363
|
+
}
|
|
23364
|
+
/**
|
|
23365
|
+
* Downloads a knowledge source URL into a File for vector store upload.
|
|
23366
|
+
*/
|
|
23367
|
+
async downloadKnowledgeSourceFile(options) {
|
|
23368
|
+
var _a;
|
|
23369
|
+
const { source, timeoutMs, logLabel } = options;
|
|
23370
|
+
const startedAtMs = Date.now();
|
|
23371
|
+
const controller = new AbortController();
|
|
23372
|
+
const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
|
|
23373
|
+
if (this.options.isVerbose) {
|
|
23374
|
+
console.info('[🤰]', 'Downloading knowledge source', {
|
|
23375
|
+
source,
|
|
23376
|
+
timeoutMs,
|
|
23377
|
+
logLabel,
|
|
23378
|
+
});
|
|
23379
|
+
}
|
|
23380
|
+
try {
|
|
23381
|
+
const response = await fetch(source, { signal: controller.signal });
|
|
23382
|
+
const contentType = (_a = response.headers.get('content-type')) !== null && _a !== void 0 ? _a : undefined;
|
|
23383
|
+
if (!response.ok) {
|
|
23384
|
+
console.error('[🤰]', 'Failed to download knowledge source', {
|
|
23385
|
+
source,
|
|
23386
|
+
status: response.status,
|
|
23387
|
+
statusText: response.statusText,
|
|
23388
|
+
contentType,
|
|
23389
|
+
elapsedMs: Date.now() - startedAtMs,
|
|
23390
|
+
logLabel,
|
|
23391
|
+
});
|
|
23392
|
+
return null;
|
|
23393
|
+
}
|
|
23394
|
+
const buffer = await response.arrayBuffer();
|
|
23395
|
+
let filename = source.split('/').pop() || 'downloaded-file';
|
|
23396
|
+
try {
|
|
23397
|
+
const url = new URL(source);
|
|
23398
|
+
filename = url.pathname.split('/').pop() || filename;
|
|
23399
|
+
}
|
|
23400
|
+
catch (error) {
|
|
23401
|
+
// Keep default filename
|
|
23402
|
+
}
|
|
23403
|
+
const file = new File([buffer], filename, contentType ? { type: contentType } : undefined);
|
|
23404
|
+
const elapsedMs = Date.now() - startedAtMs;
|
|
23405
|
+
const sizeBytes = buffer.byteLength;
|
|
23406
|
+
if (this.options.isVerbose) {
|
|
23407
|
+
console.info('[🤰]', 'Downloaded knowledge source', {
|
|
23408
|
+
source,
|
|
23409
|
+
filename,
|
|
23410
|
+
sizeBytes,
|
|
23411
|
+
contentType,
|
|
23412
|
+
elapsedMs,
|
|
23413
|
+
logLabel,
|
|
23414
|
+
});
|
|
23415
|
+
}
|
|
23416
|
+
return { file, sizeBytes, filename, elapsedMs };
|
|
23417
|
+
}
|
|
23418
|
+
catch (error) {
|
|
23419
|
+
assertsError(error);
|
|
23420
|
+
console.error('[🤰]', 'Error downloading knowledge source', {
|
|
23421
|
+
source,
|
|
23422
|
+
elapsedMs: Date.now() - startedAtMs,
|
|
23423
|
+
logLabel,
|
|
23424
|
+
error: serializeError(error),
|
|
23425
|
+
});
|
|
23426
|
+
return null;
|
|
23427
|
+
}
|
|
23428
|
+
finally {
|
|
23429
|
+
clearTimeout(timeoutId);
|
|
23430
|
+
}
|
|
23431
|
+
}
|
|
23432
|
+
/**
|
|
23433
|
+
* Logs vector store file batch diagnostics to help trace ingestion stalls or failures.
|
|
23434
|
+
*/
|
|
23435
|
+
async logVectorStoreFileBatchDiagnostics(options) {
|
|
23436
|
+
var _a, _b, _c, _d, _e;
|
|
23437
|
+
const { client, vectorStoreId, batchId, uploadedFiles, logLabel, reason } = options;
|
|
23438
|
+
if (reason === 'stalled' && !this.options.isVerbose) {
|
|
23439
|
+
return;
|
|
23440
|
+
}
|
|
23441
|
+
if (!batchId.startsWith('vsfb_')) {
|
|
23442
|
+
console.error('[🤰]', 'Vector store file batch diagnostics skipped (invalid batch id)', {
|
|
23443
|
+
vectorStoreId,
|
|
23444
|
+
batchId,
|
|
23445
|
+
reason,
|
|
23446
|
+
logLabel,
|
|
23447
|
+
});
|
|
23448
|
+
return;
|
|
23449
|
+
}
|
|
23450
|
+
const fileIdToMetadata = new Map();
|
|
23451
|
+
for (const file of uploadedFiles) {
|
|
23452
|
+
fileIdToMetadata.set(file.fileId, file);
|
|
23453
|
+
}
|
|
23454
|
+
try {
|
|
23455
|
+
const vectorStores = this.getVectorStoresApi(client);
|
|
23456
|
+
const limit = Math.min(100, Math.max(10, uploadedFiles.length));
|
|
23457
|
+
const batchFilesPage = await vectorStores.fileBatches.listFiles(batchId, {
|
|
23458
|
+
vector_store_id: vectorStoreId,
|
|
23459
|
+
limit,
|
|
23460
|
+
});
|
|
23461
|
+
const batchFiles = (_a = batchFilesPage.data) !== null && _a !== void 0 ? _a : [];
|
|
23462
|
+
const statusCounts = {
|
|
23463
|
+
in_progress: 0,
|
|
23464
|
+
completed: 0,
|
|
23465
|
+
failed: 0,
|
|
23466
|
+
cancelled: 0,
|
|
23467
|
+
};
|
|
23468
|
+
const errorSamples = [];
|
|
23469
|
+
const inProgressSamples = [];
|
|
23470
|
+
const batchFileIds = new Set();
|
|
23471
|
+
for (const file of batchFiles) {
|
|
23472
|
+
const status = (_b = file.status) !== null && _b !== void 0 ? _b : 'unknown';
|
|
23473
|
+
statusCounts[status] = ((_c = statusCounts[status]) !== null && _c !== void 0 ? _c : 0) + 1;
|
|
23474
|
+
const vectorStoreFileId = file.id;
|
|
23475
|
+
const uploadedFileId = (_d = file.file_id) !== null && _d !== void 0 ? _d : file.fileId;
|
|
23476
|
+
const fileId = uploadedFileId !== null && uploadedFileId !== void 0 ? uploadedFileId : vectorStoreFileId;
|
|
23477
|
+
batchFileIds.add(fileId);
|
|
23478
|
+
const metadata = fileIdToMetadata.get(fileId);
|
|
23479
|
+
if (status === 'failed') {
|
|
23480
|
+
errorSamples.push({
|
|
23481
|
+
fileId,
|
|
23482
|
+
status,
|
|
23483
|
+
error: (_e = file.last_error) === null || _e === void 0 ? void 0 : _e.message,
|
|
23484
|
+
filename: metadata === null || metadata === void 0 ? void 0 : metadata.filename,
|
|
23485
|
+
vectorStoreFileId: uploadedFileId ? vectorStoreFileId : undefined,
|
|
23486
|
+
});
|
|
23487
|
+
}
|
|
23488
|
+
if (status === 'in_progress') {
|
|
23489
|
+
inProgressSamples.push({
|
|
23490
|
+
fileId,
|
|
23491
|
+
filename: metadata === null || metadata === void 0 ? void 0 : metadata.filename,
|
|
23492
|
+
vectorStoreFileId: uploadedFileId ? vectorStoreFileId : undefined,
|
|
23493
|
+
});
|
|
23494
|
+
}
|
|
23495
|
+
}
|
|
23496
|
+
const missingSamples = uploadedFiles
|
|
23497
|
+
.filter((file) => !batchFileIds.has(file.fileId))
|
|
23498
|
+
.slice(0, 5)
|
|
23499
|
+
.map((file) => ({
|
|
23500
|
+
fileId: file.fileId,
|
|
23501
|
+
filename: file.filename,
|
|
23502
|
+
sizeBytes: file.sizeBytes,
|
|
23503
|
+
}));
|
|
23504
|
+
const vectorStore = await vectorStores.retrieve(vectorStoreId);
|
|
23505
|
+
const logPayload = {
|
|
23506
|
+
vectorStoreId,
|
|
23507
|
+
batchId,
|
|
23508
|
+
reason,
|
|
23509
|
+
vectorStoreStatus: vectorStore.status,
|
|
23510
|
+
vectorStoreFileCounts: vectorStore.file_counts,
|
|
23511
|
+
vectorStoreUsageBytes: vectorStore.usage_bytes,
|
|
23512
|
+
batchFileCount: batchFiles.length,
|
|
23513
|
+
statusCounts,
|
|
23514
|
+
errorSamples: errorSamples.slice(0, 5),
|
|
23515
|
+
inProgressSamples,
|
|
23516
|
+
missingFileCount: uploadedFiles.length - batchFileIds.size,
|
|
23517
|
+
missingSamples,
|
|
23518
|
+
logLabel,
|
|
23519
|
+
};
|
|
23520
|
+
const logFunction = reason === 'stalled' ? console.info : console.error;
|
|
23521
|
+
logFunction('[🤰]', 'Vector store file batch diagnostics', logPayload);
|
|
23522
|
+
}
|
|
23523
|
+
catch (error) {
|
|
23524
|
+
assertsError(error);
|
|
23525
|
+
console.error('[🤰]', 'Vector store file batch diagnostics failed', {
|
|
23526
|
+
vectorStoreId,
|
|
23527
|
+
batchId,
|
|
23528
|
+
reason,
|
|
23529
|
+
logLabel,
|
|
23530
|
+
error: serializeError(error),
|
|
23531
|
+
});
|
|
23532
|
+
}
|
|
23533
|
+
}
|
|
23534
|
+
/**
|
|
23535
|
+
* Uploads knowledge source files to the vector store and polls until processing completes.
|
|
23536
|
+
*/
|
|
23537
|
+
async uploadKnowledgeSourceFilesToVectorStore(options) {
|
|
23538
|
+
var _a, _b, _c, _d, _e, _f;
|
|
23539
|
+
const { client, vectorStoreId, files, totalBytes, logLabel } = options;
|
|
23540
|
+
const vectorStores = this.getVectorStoresApi(client);
|
|
23541
|
+
const uploadStartedAtMs = Date.now();
|
|
23542
|
+
const maxConcurrency = Math.max(1, this.getKnowledgeSourceUploadMaxConcurrency());
|
|
23543
|
+
const pollIntervalMs = Math.max(1000, this.getKnowledgeSourceUploadPollIntervalMs());
|
|
23544
|
+
const uploadTimeoutMs = Math.max(1000, this.getKnowledgeSourceUploadTimeoutMs());
|
|
23545
|
+
if (this.options.isVerbose) {
|
|
23546
|
+
console.info('[🤰]', 'Uploading knowledge source files to OpenAI', {
|
|
23547
|
+
vectorStoreId,
|
|
23548
|
+
fileCount: files.length,
|
|
23549
|
+
totalBytes,
|
|
23550
|
+
maxConcurrency,
|
|
23551
|
+
pollIntervalMs,
|
|
23552
|
+
uploadTimeoutMs,
|
|
23553
|
+
logLabel,
|
|
23554
|
+
});
|
|
23555
|
+
}
|
|
23556
|
+
const fileTypeSummary = {};
|
|
23557
|
+
for (const file of files) {
|
|
23558
|
+
const filename = (_a = file.name) !== null && _a !== void 0 ? _a : '';
|
|
23559
|
+
const extension = filename.includes('.')
|
|
23560
|
+
? (_c = (_b = filename.split('.').pop()) === null || _b === void 0 ? void 0 : _b.toLowerCase()) !== null && _c !== void 0 ? _c : 'unknown'
|
|
23561
|
+
: 'unknown';
|
|
23562
|
+
const sizeBytes = typeof file.size === 'number' ? file.size : 0;
|
|
23563
|
+
const summary = (_d = fileTypeSummary[extension]) !== null && _d !== void 0 ? _d : { count: 0, totalBytes: 0 };
|
|
23564
|
+
summary.count += 1;
|
|
23565
|
+
summary.totalBytes += sizeBytes;
|
|
23566
|
+
fileTypeSummary[extension] = summary;
|
|
23567
|
+
}
|
|
23568
|
+
if (this.options.isVerbose) {
|
|
23569
|
+
console.info('[🤰]', 'Knowledge source file summary', {
|
|
23570
|
+
vectorStoreId,
|
|
23571
|
+
fileCount: files.length,
|
|
23572
|
+
totalBytes,
|
|
23573
|
+
fileTypeSummary,
|
|
23574
|
+
logLabel,
|
|
23575
|
+
});
|
|
23576
|
+
}
|
|
23577
|
+
const fileEntries = files.map((file, index) => ({ file, index }));
|
|
23578
|
+
const fileIterator = fileEntries.values();
|
|
23579
|
+
const fileIds = [];
|
|
23580
|
+
const uploadedFiles = [];
|
|
23581
|
+
const failedUploads = [];
|
|
23582
|
+
let uploadedCount = 0;
|
|
23583
|
+
const processFiles = async (iterator) => {
|
|
23584
|
+
var _a, _b;
|
|
23585
|
+
for (const { file, index } of iterator) {
|
|
23586
|
+
const uploadIndex = index + 1;
|
|
23587
|
+
const filename = file.name || `knowledge-source-${uploadIndex}`;
|
|
23588
|
+
const extension = filename.includes('.')
|
|
23589
|
+
? (_b = (_a = filename.split('.').pop()) === null || _a === void 0 ? void 0 : _a.toLowerCase()) !== null && _b !== void 0 ? _b : 'unknown'
|
|
23590
|
+
: 'unknown';
|
|
23591
|
+
const sizeBytes = typeof file.size === 'number' ? file.size : undefined;
|
|
23592
|
+
const fileUploadStartedAtMs = Date.now();
|
|
23593
|
+
if (this.options.isVerbose) {
|
|
23594
|
+
console.info('[🤰]', 'Uploading knowledge source file', {
|
|
23595
|
+
index: uploadIndex,
|
|
23596
|
+
total: files.length,
|
|
23597
|
+
filename,
|
|
23598
|
+
extension,
|
|
23599
|
+
sizeBytes,
|
|
23600
|
+
logLabel,
|
|
23601
|
+
});
|
|
23602
|
+
}
|
|
23603
|
+
try {
|
|
23604
|
+
const uploaded = await client.files.create({ file, purpose: 'assistants' });
|
|
23605
|
+
fileIds.push(uploaded.id);
|
|
23606
|
+
uploadedFiles.push({ fileId: uploaded.id, filename, sizeBytes });
|
|
23607
|
+
uploadedCount += 1;
|
|
23608
|
+
if (this.options.isVerbose) {
|
|
23609
|
+
console.info('[🤰]', 'Uploaded knowledge source file', {
|
|
23610
|
+
index: uploadIndex,
|
|
23611
|
+
total: files.length,
|
|
23612
|
+
filename,
|
|
23613
|
+
sizeBytes,
|
|
23614
|
+
fileId: uploaded.id,
|
|
23615
|
+
elapsedMs: Date.now() - fileUploadStartedAtMs,
|
|
23616
|
+
logLabel,
|
|
23617
|
+
});
|
|
23618
|
+
}
|
|
23619
|
+
}
|
|
23620
|
+
catch (error) {
|
|
23621
|
+
assertsError(error);
|
|
23622
|
+
const serializedError = serializeError(error);
|
|
23623
|
+
failedUploads.push({ index: uploadIndex, filename, error: serializedError });
|
|
23624
|
+
console.error('[🤰]', 'Failed to upload knowledge source file', {
|
|
23625
|
+
index: uploadIndex,
|
|
23626
|
+
total: files.length,
|
|
23627
|
+
filename,
|
|
23628
|
+
sizeBytes,
|
|
23629
|
+
elapsedMs: Date.now() - fileUploadStartedAtMs,
|
|
23630
|
+
logLabel,
|
|
23631
|
+
error: serializedError,
|
|
23632
|
+
});
|
|
23633
|
+
}
|
|
23634
|
+
}
|
|
23635
|
+
};
|
|
23636
|
+
const workerCount = Math.min(maxConcurrency, files.length);
|
|
23637
|
+
const workers = Array.from({ length: workerCount }, () => processFiles(fileIterator));
|
|
23638
|
+
await Promise.all(workers);
|
|
23639
|
+
if (this.options.isVerbose) {
|
|
23640
|
+
console.info('[🤰]', 'Finished uploading knowledge source files', {
|
|
23641
|
+
vectorStoreId,
|
|
23642
|
+
fileCount: files.length,
|
|
23643
|
+
uploadedCount,
|
|
23644
|
+
failedCount: failedUploads.length,
|
|
23645
|
+
elapsedMs: Date.now() - uploadStartedAtMs,
|
|
23646
|
+
failedSamples: failedUploads.slice(0, 3),
|
|
23647
|
+
logLabel,
|
|
23648
|
+
});
|
|
23649
|
+
}
|
|
23650
|
+
if (fileIds.length === 0) {
|
|
23651
|
+
console.error('[🤰]', 'No knowledge source files were uploaded', {
|
|
23652
|
+
vectorStoreId,
|
|
23653
|
+
fileCount: files.length,
|
|
23654
|
+
failedCount: failedUploads.length,
|
|
23655
|
+
logLabel,
|
|
23656
|
+
});
|
|
23657
|
+
return null;
|
|
23658
|
+
}
|
|
23659
|
+
const batch = await vectorStores.fileBatches.create(vectorStoreId, {
|
|
23660
|
+
file_ids: fileIds,
|
|
23661
|
+
});
|
|
23662
|
+
const expectedBatchId = batch.id;
|
|
23663
|
+
const expectedBatchIdValid = expectedBatchId.startsWith('vsfb_');
|
|
23664
|
+
if (!expectedBatchIdValid) {
|
|
23665
|
+
console.error('[🤰]', 'Vector store file batch id looks invalid', {
|
|
23666
|
+
vectorStoreId,
|
|
23667
|
+
batchId: expectedBatchId,
|
|
23668
|
+
batchVectorStoreId: batch.vector_store_id,
|
|
23669
|
+
logLabel,
|
|
23670
|
+
});
|
|
23671
|
+
}
|
|
23672
|
+
else if (batch.vector_store_id !== vectorStoreId) {
|
|
23673
|
+
console.error('[🤰]', 'Vector store file batch vector store id mismatch', {
|
|
23674
|
+
vectorStoreId,
|
|
23675
|
+
batchId: expectedBatchId,
|
|
23676
|
+
batchVectorStoreId: batch.vector_store_id,
|
|
23677
|
+
logLabel,
|
|
23678
|
+
});
|
|
23679
|
+
}
|
|
23680
|
+
if (this.options.isVerbose) {
|
|
23681
|
+
console.info('[🤰]', 'Created vector store file batch', {
|
|
23682
|
+
vectorStoreId,
|
|
23683
|
+
batchId: expectedBatchId,
|
|
23684
|
+
fileCount: fileIds.length,
|
|
23685
|
+
logLabel,
|
|
23686
|
+
});
|
|
23687
|
+
}
|
|
23688
|
+
const pollStartedAtMs = Date.now();
|
|
23689
|
+
const progressLogIntervalMs = Math.max(VECTOR_STORE_PROGRESS_LOG_INTERVAL_MIN_MS, pollIntervalMs);
|
|
23690
|
+
const diagnosticsIntervalMs = Math.max(60000, pollIntervalMs * 5);
|
|
23691
|
+
// let lastStatus: string | undefined;
|
|
23692
|
+
let lastCountsKey = '';
|
|
23693
|
+
let lastProgressKey = '';
|
|
23694
|
+
let lastLogAtMs = 0;
|
|
23695
|
+
let lastProgressAtMs = pollStartedAtMs;
|
|
23696
|
+
let lastDiagnosticsAtMs = pollStartedAtMs;
|
|
23697
|
+
let latestBatch = batch;
|
|
23698
|
+
let loggedBatchIdMismatch = false;
|
|
23699
|
+
let loggedBatchIdFallback = false;
|
|
23700
|
+
let loggedBatchIdInvalid = false;
|
|
23701
|
+
let shouldPoll = true;
|
|
23702
|
+
while (shouldPoll) {
|
|
23703
|
+
const nowMs = Date.now();
|
|
23704
|
+
// [🤰] Note: Sometimes OpenAI returns Vector Store object instead of Batch object, or IDs get swapped.
|
|
23705
|
+
const rawBatchId = typeof latestBatch.id === 'string' ? latestBatch.id : '';
|
|
23706
|
+
const rawVectorStoreId = latestBatch.vector_store_id;
|
|
23707
|
+
let returnedBatchId = rawBatchId;
|
|
23708
|
+
let returnedBatchIdValid = typeof returnedBatchId === 'string' && returnedBatchId.startsWith('vsfb_');
|
|
23709
|
+
if (!returnedBatchIdValid && expectedBatchIdValid) {
|
|
23710
|
+
if (!loggedBatchIdFallback) {
|
|
23711
|
+
console.error('[🤰]', 'Vector store file batch id missing from response; falling back to expected', {
|
|
23712
|
+
vectorStoreId,
|
|
23713
|
+
expectedBatchId,
|
|
23714
|
+
returnedBatchId,
|
|
23715
|
+
rawVectorStoreId,
|
|
23716
|
+
logLabel,
|
|
23717
|
+
});
|
|
23718
|
+
loggedBatchIdFallback = true;
|
|
23719
|
+
}
|
|
23720
|
+
returnedBatchId = expectedBatchId;
|
|
23721
|
+
returnedBatchIdValid = true;
|
|
23722
|
+
}
|
|
23723
|
+
if (!returnedBatchIdValid && !loggedBatchIdInvalid) {
|
|
23724
|
+
console.error('[🤰]', 'Vector store file batch id is invalid; stopping polling', {
|
|
23725
|
+
vectorStoreId,
|
|
23726
|
+
expectedBatchId,
|
|
23727
|
+
returnedBatchId,
|
|
23728
|
+
rawVectorStoreId,
|
|
23729
|
+
logLabel,
|
|
23730
|
+
});
|
|
23731
|
+
loggedBatchIdInvalid = true;
|
|
23732
|
+
}
|
|
23733
|
+
const batchIdMismatch = expectedBatchIdValid && returnedBatchIdValid && returnedBatchId !== expectedBatchId;
|
|
23734
|
+
if (batchIdMismatch && !loggedBatchIdMismatch) {
|
|
23735
|
+
console.error('[🤰]', 'Vector store file batch id mismatch', {
|
|
23736
|
+
vectorStoreId,
|
|
23737
|
+
expectedBatchId,
|
|
23738
|
+
returnedBatchId,
|
|
23739
|
+
logLabel,
|
|
23740
|
+
});
|
|
23741
|
+
loggedBatchIdMismatch = true;
|
|
23742
|
+
}
|
|
23743
|
+
if (returnedBatchIdValid) {
|
|
23744
|
+
latestBatch = await vectorStores.fileBatches.retrieve(returnedBatchId, {
|
|
23745
|
+
vector_store_id: vectorStoreId,
|
|
23746
|
+
});
|
|
23747
|
+
}
|
|
23748
|
+
else {
|
|
23749
|
+
shouldPoll = false;
|
|
23750
|
+
continue;
|
|
23751
|
+
}
|
|
23752
|
+
const status = (_e = latestBatch.status) !== null && _e !== void 0 ? _e : 'unknown';
|
|
23753
|
+
const fileCounts = (_f = latestBatch.file_counts) !== null && _f !== void 0 ? _f : {};
|
|
23754
|
+
const progressKey = JSON.stringify(fileCounts);
|
|
23755
|
+
const statusCountsKey = `${status}-${progressKey}`;
|
|
23756
|
+
const isProgressing = progressKey !== lastProgressKey;
|
|
23757
|
+
if (isProgressing) {
|
|
23758
|
+
lastProgressAtMs = nowMs;
|
|
23759
|
+
lastProgressKey = progressKey;
|
|
23760
|
+
}
|
|
23761
|
+
if (this.options.isVerbose &&
|
|
23762
|
+
(statusCountsKey !== lastCountsKey || nowMs - lastLogAtMs >= progressLogIntervalMs)) {
|
|
23763
|
+
console.info('[🤰]', 'Vector store file batch status', {
|
|
23764
|
+
vectorStoreId,
|
|
23765
|
+
batchId: returnedBatchId,
|
|
23766
|
+
status,
|
|
23767
|
+
fileCounts,
|
|
23768
|
+
elapsedMs: nowMs - pollStartedAtMs,
|
|
23769
|
+
logLabel,
|
|
23770
|
+
});
|
|
23771
|
+
lastCountsKey = statusCountsKey;
|
|
23772
|
+
lastLogAtMs = nowMs;
|
|
23773
|
+
}
|
|
23774
|
+
if (status === 'in_progress' &&
|
|
23775
|
+
nowMs - lastProgressAtMs >= VECTOR_STORE_STALL_LOG_THRESHOLD_MS &&
|
|
23776
|
+
nowMs - lastDiagnosticsAtMs >= diagnosticsIntervalMs) {
|
|
23777
|
+
lastDiagnosticsAtMs = nowMs;
|
|
23778
|
+
await this.logVectorStoreFileBatchDiagnostics({
|
|
23779
|
+
client,
|
|
23780
|
+
vectorStoreId,
|
|
23781
|
+
batchId: returnedBatchId,
|
|
23782
|
+
uploadedFiles,
|
|
23783
|
+
logLabel,
|
|
23784
|
+
reason: 'stalled',
|
|
23785
|
+
});
|
|
23786
|
+
}
|
|
23787
|
+
if (status === 'completed') {
|
|
23788
|
+
if (this.options.isVerbose) {
|
|
23789
|
+
console.info('[🤰]', 'Vector store file batch completed', {
|
|
23790
|
+
vectorStoreId,
|
|
23791
|
+
batchId: returnedBatchId,
|
|
23792
|
+
fileCounts,
|
|
23793
|
+
elapsedMs: nowMs - pollStartedAtMs,
|
|
23794
|
+
logLabel,
|
|
23795
|
+
});
|
|
23796
|
+
}
|
|
23797
|
+
shouldPoll = false;
|
|
23798
|
+
continue;
|
|
23799
|
+
}
|
|
23800
|
+
if (status === 'failed') {
|
|
23801
|
+
console.error('[🤰]', 'Vector store file batch completed with failures', {
|
|
23802
|
+
vectorStoreId,
|
|
23803
|
+
batchId: returnedBatchId,
|
|
23804
|
+
fileCounts,
|
|
23805
|
+
elapsedMs: nowMs - pollStartedAtMs,
|
|
23806
|
+
logLabel,
|
|
23807
|
+
});
|
|
23808
|
+
await this.logVectorStoreFileBatchDiagnostics({
|
|
23809
|
+
client,
|
|
23810
|
+
vectorStoreId,
|
|
23811
|
+
batchId: returnedBatchId,
|
|
23812
|
+
uploadedFiles,
|
|
23813
|
+
logLabel,
|
|
23814
|
+
reason: 'failed',
|
|
23815
|
+
});
|
|
23816
|
+
shouldPoll = false;
|
|
23817
|
+
continue;
|
|
23818
|
+
}
|
|
23819
|
+
if (status === 'cancelled') {
|
|
23820
|
+
console.error('[🤰]', 'Vector store file batch did not complete', {
|
|
23821
|
+
vectorStoreId,
|
|
23822
|
+
batchId: returnedBatchId,
|
|
23823
|
+
status,
|
|
23824
|
+
fileCounts,
|
|
23825
|
+
elapsedMs: nowMs - pollStartedAtMs,
|
|
23826
|
+
logLabel,
|
|
23827
|
+
});
|
|
23828
|
+
await this.logVectorStoreFileBatchDiagnostics({
|
|
23829
|
+
client,
|
|
23830
|
+
vectorStoreId,
|
|
23831
|
+
batchId: returnedBatchId,
|
|
23832
|
+
uploadedFiles,
|
|
23833
|
+
logLabel,
|
|
23834
|
+
reason: 'failed',
|
|
23835
|
+
});
|
|
23836
|
+
shouldPoll = false;
|
|
23837
|
+
continue;
|
|
23838
|
+
}
|
|
23839
|
+
if (nowMs - pollStartedAtMs >= uploadTimeoutMs) {
|
|
23840
|
+
console.error('[🤰]', 'Timed out waiting for vector store file batch', {
|
|
23841
|
+
vectorStoreId,
|
|
23842
|
+
batchId: returnedBatchId,
|
|
23843
|
+
fileCounts,
|
|
23844
|
+
elapsedMs: nowMs - pollStartedAtMs,
|
|
23845
|
+
uploadTimeoutMs,
|
|
23846
|
+
logLabel,
|
|
23847
|
+
});
|
|
23848
|
+
await this.logVectorStoreFileBatchDiagnostics({
|
|
23849
|
+
client,
|
|
23850
|
+
vectorStoreId,
|
|
23851
|
+
batchId: returnedBatchId,
|
|
23852
|
+
uploadedFiles,
|
|
23853
|
+
logLabel,
|
|
23854
|
+
reason: 'timeout',
|
|
23855
|
+
});
|
|
23856
|
+
if (this.shouldContinueOnVectorStoreStall()) {
|
|
23857
|
+
console.warn('[🤰]', 'Continuing despite vector store timeout as requested', {
|
|
23858
|
+
vectorStoreId,
|
|
23859
|
+
logLabel,
|
|
23860
|
+
});
|
|
23861
|
+
shouldPoll = false;
|
|
23862
|
+
continue;
|
|
23863
|
+
}
|
|
23864
|
+
try {
|
|
23865
|
+
const cancelBatchId = batchIdMismatch && returnedBatchId.startsWith('vsfb_') ? returnedBatchId : expectedBatchId;
|
|
23866
|
+
if (!cancelBatchId.startsWith('vsfb_')) {
|
|
23867
|
+
console.error('[🤰]', 'Skipping vector store file batch cancel (invalid batch id)', {
|
|
23868
|
+
vectorStoreId,
|
|
23869
|
+
batchId: cancelBatchId,
|
|
23870
|
+
logLabel,
|
|
23871
|
+
});
|
|
23872
|
+
}
|
|
23873
|
+
else {
|
|
23874
|
+
await vectorStores.fileBatches.cancel(cancelBatchId, {
|
|
23875
|
+
vector_store_id: vectorStoreId,
|
|
23876
|
+
});
|
|
23877
|
+
}
|
|
23878
|
+
if (this.options.isVerbose) {
|
|
23879
|
+
console.info('[🤰]', 'Cancelled vector store file batch after timeout', {
|
|
23880
|
+
vectorStoreId,
|
|
23881
|
+
batchId: batchIdMismatch && returnedBatchId.startsWith('vsfb_')
|
|
23882
|
+
? returnedBatchId
|
|
23883
|
+
: expectedBatchId,
|
|
23884
|
+
...(batchIdMismatch ? { returnedBatchId } : {}),
|
|
23885
|
+
logLabel,
|
|
23886
|
+
});
|
|
23887
|
+
}
|
|
23888
|
+
}
|
|
23889
|
+
catch (error) {
|
|
23890
|
+
assertsError(error);
|
|
23891
|
+
console.error('[🤰]', 'Failed to cancel vector store file batch after timeout', {
|
|
23892
|
+
vectorStoreId,
|
|
23893
|
+
batchId: expectedBatchId,
|
|
23894
|
+
...(batchIdMismatch ? { returnedBatchId } : {}),
|
|
23895
|
+
logLabel,
|
|
23896
|
+
error: serializeError(error),
|
|
23897
|
+
});
|
|
23898
|
+
}
|
|
23899
|
+
shouldPoll = false;
|
|
23900
|
+
continue;
|
|
23901
|
+
}
|
|
23902
|
+
await new Promise((resolve) => setTimeout(resolve, pollIntervalMs));
|
|
23903
|
+
}
|
|
23904
|
+
return latestBatch;
|
|
23905
|
+
}
|
|
23906
|
+
/**
|
|
23907
|
+
* Creates a vector store and uploads knowledge sources, returning its ID.
|
|
23908
|
+
*/
|
|
23909
|
+
async createVectorStoreWithKnowledgeSources(options) {
|
|
23910
|
+
const { client, name, knowledgeSources, logLabel } = options;
|
|
23911
|
+
const vectorStores = this.getVectorStoresApi(client);
|
|
23912
|
+
const knowledgeSourcesCount = knowledgeSources.length;
|
|
23913
|
+
const downloadTimeoutMs = this.getKnowledgeSourceDownloadTimeoutMs();
|
|
23914
|
+
if (this.options.isVerbose) {
|
|
23915
|
+
console.info('[🤰]', 'Creating vector store with knowledge sources', {
|
|
23916
|
+
name,
|
|
23917
|
+
knowledgeSourcesCount,
|
|
23918
|
+
downloadTimeoutMs,
|
|
23919
|
+
logLabel,
|
|
23920
|
+
});
|
|
23921
|
+
}
|
|
23922
|
+
const vectorStore = await vectorStores.create({
|
|
23923
|
+
name: `${name} Knowledge Base`,
|
|
23924
|
+
});
|
|
23925
|
+
const vectorStoreId = vectorStore.id;
|
|
23926
|
+
if (this.options.isVerbose) {
|
|
23927
|
+
console.info('[🤰]', 'Vector store created', {
|
|
23928
|
+
vectorStoreId,
|
|
23929
|
+
logLabel,
|
|
23930
|
+
});
|
|
23931
|
+
}
|
|
23932
|
+
const fileStreams = [];
|
|
23933
|
+
const skippedSources = [];
|
|
23934
|
+
let totalBytes = 0;
|
|
23935
|
+
const processingStartedAtMs = Date.now();
|
|
23936
|
+
for (const [index, source] of knowledgeSources.entries()) {
|
|
23937
|
+
try {
|
|
23938
|
+
const sourceType = source.startsWith('http') || source.startsWith('https') ? 'url' : 'file';
|
|
23939
|
+
if (this.options.isVerbose) {
|
|
23940
|
+
console.info('[🤰]', 'Processing knowledge source', {
|
|
23941
|
+
index: index + 1,
|
|
23942
|
+
total: knowledgeSourcesCount,
|
|
23943
|
+
source,
|
|
23944
|
+
sourceType,
|
|
23945
|
+
logLabel,
|
|
23946
|
+
});
|
|
23947
|
+
}
|
|
23948
|
+
// Check if it's a URL
|
|
23949
|
+
if (source.startsWith('http://') || source.startsWith('https://')) {
|
|
23950
|
+
const downloadResult = await this.downloadKnowledgeSourceFile({
|
|
23951
|
+
source,
|
|
23952
|
+
timeoutMs: downloadTimeoutMs,
|
|
23953
|
+
logLabel,
|
|
23954
|
+
});
|
|
23955
|
+
if (downloadResult) {
|
|
23956
|
+
fileStreams.push(downloadResult.file);
|
|
23957
|
+
totalBytes += downloadResult.sizeBytes;
|
|
23958
|
+
}
|
|
23959
|
+
else {
|
|
23960
|
+
skippedSources.push({ source, reason: 'download_failed' });
|
|
23961
|
+
}
|
|
23962
|
+
}
|
|
23963
|
+
else {
|
|
23964
|
+
skippedSources.push({ source, reason: 'unsupported_source_type' });
|
|
23965
|
+
if (this.options.isVerbose) {
|
|
23966
|
+
console.info('[🤰]', 'Skipping knowledge source (unsupported type)', {
|
|
23967
|
+
source,
|
|
23968
|
+
sourceType,
|
|
23969
|
+
logLabel,
|
|
23970
|
+
});
|
|
23971
|
+
}
|
|
23972
|
+
/*
|
|
23973
|
+
TODO: [🤰] Resolve problem with browser environment
|
|
23974
|
+
// Assume it's a local file path
|
|
23975
|
+
// Note: This will work in Node.js environment
|
|
23976
|
+
// For browser environments, this would need different handling
|
|
23977
|
+
const fs = await import('fs');
|
|
23978
|
+
const fileStream = fs.createReadStream(source);
|
|
23979
|
+
fileStreams.push(fileStream);
|
|
23980
|
+
*/
|
|
23981
|
+
}
|
|
23982
|
+
}
|
|
23983
|
+
catch (error) {
|
|
23984
|
+
assertsError(error);
|
|
23985
|
+
skippedSources.push({ source, reason: 'processing_error' });
|
|
23986
|
+
console.error('[🤰]', 'Error processing knowledge source', {
|
|
23987
|
+
source,
|
|
23988
|
+
logLabel,
|
|
23989
|
+
error: serializeError(error),
|
|
23990
|
+
});
|
|
23991
|
+
}
|
|
23992
|
+
}
|
|
23993
|
+
if (this.options.isVerbose) {
|
|
23994
|
+
console.info('[🤰]', 'Finished processing knowledge sources', {
|
|
23995
|
+
total: knowledgeSourcesCount,
|
|
23996
|
+
downloadedCount: fileStreams.length,
|
|
23997
|
+
skippedCount: skippedSources.length,
|
|
23998
|
+
totalBytes,
|
|
23999
|
+
elapsedMs: Date.now() - processingStartedAtMs,
|
|
24000
|
+
skippedSamples: skippedSources.slice(0, 3),
|
|
24001
|
+
logLabel,
|
|
24002
|
+
});
|
|
24003
|
+
}
|
|
24004
|
+
if (fileStreams.length > 0) {
|
|
24005
|
+
if (this.options.isVerbose) {
|
|
24006
|
+
console.info('[🤰]', 'Uploading files to vector store', {
|
|
24007
|
+
vectorStoreId,
|
|
24008
|
+
fileCount: fileStreams.length,
|
|
24009
|
+
totalBytes,
|
|
24010
|
+
maxConcurrency: this.getKnowledgeSourceUploadMaxConcurrency(),
|
|
24011
|
+
pollIntervalMs: this.getKnowledgeSourceUploadPollIntervalMs(),
|
|
24012
|
+
uploadTimeoutMs: this.getKnowledgeSourceUploadTimeoutMs(),
|
|
24013
|
+
logLabel,
|
|
24014
|
+
});
|
|
24015
|
+
}
|
|
24016
|
+
try {
|
|
24017
|
+
await this.uploadKnowledgeSourceFilesToVectorStore({
|
|
24018
|
+
client,
|
|
24019
|
+
vectorStoreId,
|
|
24020
|
+
files: fileStreams,
|
|
24021
|
+
totalBytes,
|
|
24022
|
+
logLabel,
|
|
24023
|
+
});
|
|
24024
|
+
}
|
|
24025
|
+
catch (error) {
|
|
24026
|
+
assertsError(error);
|
|
24027
|
+
console.error('[🤰]', 'Error uploading files to vector store', {
|
|
24028
|
+
vectorStoreId,
|
|
24029
|
+
logLabel,
|
|
24030
|
+
error: serializeError(error),
|
|
24031
|
+
});
|
|
24032
|
+
}
|
|
24033
|
+
}
|
|
24034
|
+
else if (this.options.isVerbose) {
|
|
24035
|
+
console.info('[🤰]', 'No knowledge source files to upload', {
|
|
24036
|
+
vectorStoreId,
|
|
24037
|
+
skippedCount: skippedSources.length,
|
|
24038
|
+
logLabel,
|
|
24039
|
+
});
|
|
24040
|
+
}
|
|
24041
|
+
return {
|
|
24042
|
+
vectorStoreId,
|
|
24043
|
+
uploadedFileCount: fileStreams.length,
|
|
24044
|
+
skippedCount: skippedSources.length,
|
|
24045
|
+
totalBytes,
|
|
24046
|
+
};
|
|
24047
|
+
}
|
|
24048
|
+
}
|
|
24049
|
+
|
|
24050
|
+
const DEFAULT_AGENT_KIT_MODEL_NAME = 'gpt-5.2';
|
|
24051
|
+
/**
|
|
24052
|
+
* Execution tools for OpenAI AgentKit (Agents SDK).
|
|
24053
|
+
*
|
|
24054
|
+
* @public exported from `@promptbook/openai`
|
|
24055
|
+
*/
|
|
24056
|
+
class OpenAiAgentKitExecutionTools extends OpenAiVectorStoreHandler {
|
|
24057
|
+
/**
|
|
24058
|
+
* Creates OpenAI AgentKit execution tools.
|
|
24059
|
+
*/
|
|
24060
|
+
constructor(options) {
|
|
24061
|
+
var _a;
|
|
24062
|
+
if (options.isProxied) {
|
|
24063
|
+
throw new NotYetImplementedError(`Proxy mode is not yet implemented for OpenAI AgentKit`);
|
|
24064
|
+
}
|
|
24065
|
+
super(options);
|
|
24066
|
+
this.preparedAgentKitAgent = null;
|
|
24067
|
+
this.agentKitModelName = (_a = options.agentKitModelName) !== null && _a !== void 0 ? _a : DEFAULT_AGENT_KIT_MODEL_NAME;
|
|
24068
|
+
}
|
|
24069
|
+
get title() {
|
|
24070
|
+
return 'OpenAI AgentKit';
|
|
24071
|
+
}
|
|
24072
|
+
get description() {
|
|
24073
|
+
return 'Use OpenAI AgentKit for agent-style chat with tools and knowledge';
|
|
24074
|
+
}
|
|
24075
|
+
/**
|
|
24076
|
+
* Calls OpenAI AgentKit with a chat prompt (non-streaming).
|
|
24077
|
+
*/
|
|
24078
|
+
async callChatModel(prompt) {
|
|
24079
|
+
return this.callChatModelStream(prompt, () => { });
|
|
24080
|
+
}
|
|
24081
|
+
/**
|
|
24082
|
+
* Calls OpenAI AgentKit with a chat prompt (streaming).
|
|
24083
|
+
*/
|
|
24084
|
+
async callChatModelStream(prompt, onProgress) {
|
|
24085
|
+
const { content, parameters, modelRequirements } = prompt;
|
|
24086
|
+
if (modelRequirements.modelVariant !== 'CHAT') {
|
|
24087
|
+
throw new PipelineExecutionError('Use callChatModel only for CHAT variant');
|
|
24088
|
+
}
|
|
24089
|
+
for (const key of ['maxTokens', 'modelName', 'seed', 'temperature']) {
|
|
24090
|
+
if (modelRequirements[key] !== undefined) {
|
|
24091
|
+
throw new NotYetImplementedError(`In \`OpenAiAgentKitExecutionTools\` you cannot specify \`${key}\``);
|
|
24092
|
+
}
|
|
24093
|
+
}
|
|
24094
|
+
const rawPromptContent = templateParameters(content, {
|
|
24095
|
+
...parameters,
|
|
24096
|
+
modelName: this.agentKitModelName,
|
|
24097
|
+
});
|
|
24098
|
+
const preparedAgentKitAgent = await this.prepareAgentKitAgent({
|
|
24099
|
+
name: (prompt.title || 'Agent'),
|
|
24100
|
+
instructions: modelRequirements.systemMessage || '',
|
|
24101
|
+
knowledgeSources: modelRequirements.knowledgeSources,
|
|
24102
|
+
tools: 'tools' in prompt && Array.isArray(prompt.tools) ? prompt.tools : modelRequirements.tools,
|
|
24103
|
+
});
|
|
24104
|
+
return this.callChatModelStreamWithPreparedAgent({
|
|
24105
|
+
openAiAgentKitAgent: preparedAgentKitAgent.agent,
|
|
24106
|
+
prompt,
|
|
24107
|
+
rawPromptContent,
|
|
24108
|
+
onProgress,
|
|
24109
|
+
});
|
|
24110
|
+
}
|
|
24111
|
+
/**
|
|
24112
|
+
* Returns a prepared AgentKit agent when the server wants to manage caching externally.
|
|
24113
|
+
*/
|
|
24114
|
+
getPreparedAgentKitAgent() {
|
|
24115
|
+
return this.preparedAgentKitAgent;
|
|
24116
|
+
}
|
|
24117
|
+
/**
|
|
24118
|
+
* Stores a prepared AgentKit agent for later reuse by external cache managers.
|
|
24119
|
+
*/
|
|
24120
|
+
setPreparedAgentKitAgent(preparedAgent) {
|
|
24121
|
+
this.preparedAgentKitAgent = preparedAgent;
|
|
24122
|
+
}
|
|
24123
|
+
/**
|
|
24124
|
+
* Creates a new tools instance bound to a prepared AgentKit agent.
|
|
24125
|
+
*/
|
|
24126
|
+
getPreparedAgentTools(preparedAgent) {
|
|
24127
|
+
const tools = new OpenAiAgentKitExecutionTools(this.agentKitOptions);
|
|
24128
|
+
tools.setPreparedAgentKitAgent(preparedAgent);
|
|
24129
|
+
return tools;
|
|
24130
|
+
}
|
|
24131
|
+
/**
|
|
24132
|
+
* Prepares an AgentKit agent with optional knowledge sources and tool definitions.
|
|
24133
|
+
*/
|
|
24134
|
+
async prepareAgentKitAgent(options) {
|
|
24135
|
+
var _a, _b;
|
|
24136
|
+
const { name, instructions, knowledgeSources, tools, vectorStoreId: cachedVectorStoreId, storeAsPrepared, } = options;
|
|
24137
|
+
await this.ensureAgentKitDefaults();
|
|
24138
|
+
if (this.options.isVerbose) {
|
|
24139
|
+
console.info('[🤰]', 'Preparing OpenAI AgentKit agent', {
|
|
24140
|
+
name,
|
|
24141
|
+
instructionsLength: instructions.length,
|
|
24142
|
+
knowledgeSourcesCount: (_a = knowledgeSources === null || knowledgeSources === void 0 ? void 0 : knowledgeSources.length) !== null && _a !== void 0 ? _a : 0,
|
|
24143
|
+
toolsCount: (_b = tools === null || tools === void 0 ? void 0 : tools.length) !== null && _b !== void 0 ? _b : 0,
|
|
24144
|
+
});
|
|
24145
|
+
}
|
|
24146
|
+
let vectorStoreId = cachedVectorStoreId;
|
|
24147
|
+
if (!vectorStoreId && knowledgeSources && knowledgeSources.length > 0) {
|
|
24148
|
+
const vectorStoreResult = await this.createVectorStoreWithKnowledgeSources({
|
|
24149
|
+
client: await this.getClient(),
|
|
24150
|
+
name,
|
|
24151
|
+
knowledgeSources,
|
|
24152
|
+
logLabel: 'agentkit preparation',
|
|
24153
|
+
});
|
|
24154
|
+
vectorStoreId = vectorStoreResult.vectorStoreId;
|
|
24155
|
+
}
|
|
24156
|
+
else if (vectorStoreId && this.options.isVerbose) {
|
|
24157
|
+
console.info('[🤰]', 'Using cached vector store for AgentKit agent', {
|
|
24158
|
+
name,
|
|
24159
|
+
vectorStoreId,
|
|
24160
|
+
});
|
|
24161
|
+
}
|
|
24162
|
+
const agentKitTools = this.buildAgentKitTools({ tools, vectorStoreId });
|
|
24163
|
+
const openAiAgentKitAgent = new agents.Agent({
|
|
24164
|
+
name,
|
|
24165
|
+
model: this.agentKitModelName,
|
|
24166
|
+
instructions: instructions || 'You are a helpful assistant.',
|
|
24167
|
+
tools: agentKitTools,
|
|
24168
|
+
});
|
|
24169
|
+
const preparedAgent = {
|
|
24170
|
+
agent: openAiAgentKitAgent,
|
|
24171
|
+
vectorStoreId,
|
|
24172
|
+
};
|
|
24173
|
+
if (storeAsPrepared) {
|
|
24174
|
+
this.setPreparedAgentKitAgent(preparedAgent);
|
|
24175
|
+
}
|
|
24176
|
+
if (this.options.isVerbose) {
|
|
24177
|
+
console.info('[🤰]', 'OpenAI AgentKit agent ready', {
|
|
24178
|
+
name,
|
|
24179
|
+
model: this.agentKitModelName,
|
|
24180
|
+
toolCount: agentKitTools.length,
|
|
24181
|
+
hasVectorStore: Boolean(vectorStoreId),
|
|
24182
|
+
});
|
|
24183
|
+
}
|
|
24184
|
+
return preparedAgent;
|
|
24185
|
+
}
|
|
24186
|
+
/**
|
|
24187
|
+
* Ensures the AgentKit SDK is wired to the OpenAI client and API key.
|
|
24188
|
+
*/
|
|
24189
|
+
async ensureAgentKitDefaults() {
|
|
24190
|
+
const client = await this.getClient();
|
|
24191
|
+
agents.setDefaultOpenAIClient(client);
|
|
24192
|
+
const apiKey = this.agentKitOptions.apiKey;
|
|
24193
|
+
if (apiKey && typeof apiKey === 'string') {
|
|
24194
|
+
agents.setDefaultOpenAIKey(apiKey);
|
|
24195
|
+
}
|
|
24196
|
+
}
|
|
24197
|
+
/**
|
|
24198
|
+
* Builds the tool list for AgentKit, including hosted file search when applicable.
|
|
24199
|
+
*/
|
|
24200
|
+
buildAgentKitTools(options) {
|
|
24201
|
+
var _a;
|
|
24202
|
+
const { tools, vectorStoreId } = options;
|
|
24203
|
+
const agentKitTools = [];
|
|
24204
|
+
if (vectorStoreId) {
|
|
24205
|
+
agentKitTools.push(agents.fileSearchTool(vectorStoreId));
|
|
24206
|
+
}
|
|
24207
|
+
if (tools && tools.length > 0) {
|
|
24208
|
+
const scriptTools = this.resolveScriptTools();
|
|
24209
|
+
for (const toolDefinition of tools) {
|
|
24210
|
+
agentKitTools.push(agents.tool({
|
|
24211
|
+
name: toolDefinition.name,
|
|
24212
|
+
description: toolDefinition.description,
|
|
24213
|
+
parameters: toolDefinition.parameters
|
|
24214
|
+
? {
|
|
24215
|
+
...toolDefinition.parameters,
|
|
24216
|
+
additionalProperties: false,
|
|
24217
|
+
required: (_a = toolDefinition.parameters.required) !== null && _a !== void 0 ? _a : [],
|
|
24218
|
+
}
|
|
24219
|
+
: undefined,
|
|
24220
|
+
strict: false,
|
|
24221
|
+
execute: async (input, runContext, details) => {
|
|
24222
|
+
var _a, _b, _c;
|
|
24223
|
+
const scriptTool = scriptTools[0];
|
|
24224
|
+
const functionName = toolDefinition.name;
|
|
24225
|
+
const calledAt = $getCurrentDate();
|
|
24226
|
+
const callId = (_a = details === null || details === void 0 ? void 0 : details.toolCall) === null || _a === void 0 ? void 0 : _a.callId;
|
|
24227
|
+
const functionArgs = input !== null && input !== void 0 ? input : {};
|
|
24228
|
+
if (this.options.isVerbose) {
|
|
24229
|
+
console.info('[🤰]', 'Executing AgentKit tool', {
|
|
24230
|
+
functionName,
|
|
24231
|
+
callId,
|
|
24232
|
+
calledAt,
|
|
24233
|
+
});
|
|
24234
|
+
}
|
|
24235
|
+
try {
|
|
24236
|
+
return await scriptTool.execute({
|
|
24237
|
+
scriptLanguage: 'javascript',
|
|
24238
|
+
script: `
|
|
24239
|
+
const args = ${JSON.stringify(functionArgs)};
|
|
24240
|
+
return await ${functionName}(args);
|
|
24241
|
+
`,
|
|
24242
|
+
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 : {},
|
|
24243
|
+
});
|
|
24244
|
+
}
|
|
24245
|
+
catch (error) {
|
|
24246
|
+
assertsError(error);
|
|
24247
|
+
const serializedError = serializeError(error);
|
|
24248
|
+
const errorMessage = spaceTrim__default["default"]((block) => `
|
|
24249
|
+
|
|
24250
|
+
The invoked tool \`${functionName}\` failed with error:
|
|
24251
|
+
|
|
24252
|
+
\`\`\`json
|
|
24253
|
+
${block(JSON.stringify(serializedError, null, 4))}
|
|
24254
|
+
\`\`\`
|
|
24255
|
+
|
|
24256
|
+
`);
|
|
24257
|
+
console.error('[🤰]', 'AgentKit tool execution failed', {
|
|
24258
|
+
functionName,
|
|
24259
|
+
callId,
|
|
24260
|
+
error: serializedError,
|
|
24261
|
+
});
|
|
24262
|
+
return errorMessage;
|
|
24263
|
+
}
|
|
24264
|
+
},
|
|
24265
|
+
}));
|
|
24266
|
+
}
|
|
24267
|
+
}
|
|
24268
|
+
return agentKitTools;
|
|
24269
|
+
}
|
|
24270
|
+
/**
|
|
24271
|
+
* Resolves the configured script tools for tool execution.
|
|
23313
24272
|
*/
|
|
23314
|
-
|
|
23315
|
-
|
|
23316
|
-
|
|
23317
|
-
|
|
23318
|
-
|
|
23319
|
-
|
|
23320
|
-
* Execution Tools for calling OpenAI API using the Responses API (Agents)
|
|
23321
|
-
*
|
|
23322
|
-
* @public exported from `@promptbook/openai`
|
|
23323
|
-
*/
|
|
23324
|
-
class OpenAiAgentExecutionTools extends OpenAiExecutionTools {
|
|
23325
|
-
constructor(options) {
|
|
23326
|
-
super(options);
|
|
23327
|
-
this.vectorStoreId = options.vectorStoreId;
|
|
23328
|
-
}
|
|
23329
|
-
get title() {
|
|
23330
|
-
return 'OpenAI Agent';
|
|
23331
|
-
}
|
|
23332
|
-
get description() {
|
|
23333
|
-
return 'Use OpenAI Responses API (Agentic)';
|
|
24273
|
+
resolveScriptTools() {
|
|
24274
|
+
const executionTools = this.options.executionTools;
|
|
24275
|
+
if (!executionTools || !executionTools.script) {
|
|
24276
|
+
throw new PipelineExecutionError(`Model requested tools but no executionTools.script were provided in OpenAiAgentKitExecutionTools options`);
|
|
24277
|
+
}
|
|
24278
|
+
return Array.isArray(executionTools.script) ? executionTools.script : [executionTools.script];
|
|
23334
24279
|
}
|
|
23335
24280
|
/**
|
|
23336
|
-
*
|
|
24281
|
+
* Runs a prepared AgentKit agent and streams results back to the caller.
|
|
23337
24282
|
*/
|
|
23338
|
-
async
|
|
23339
|
-
|
|
23340
|
-
|
|
23341
|
-
|
|
23342
|
-
|
|
23343
|
-
|
|
23344
|
-
if (modelRequirements.modelVariant !== 'CHAT') {
|
|
23345
|
-
throw new PipelineExecutionError('Use callChatModel only for CHAT variant');
|
|
23346
|
-
}
|
|
23347
|
-
const rawPromptContent = templateParameters(content, {
|
|
23348
|
-
...parameters,
|
|
23349
|
-
modelName: 'agent',
|
|
23350
|
-
});
|
|
23351
|
-
// Build input items
|
|
23352
|
-
const input = []; // TODO: Type properly when OpenAI types are updated
|
|
23353
|
-
// Add previous messages from thread (if any)
|
|
23354
|
-
if ('thread' in prompt && Array.isArray(prompt.thread)) {
|
|
23355
|
-
const previousMessages = prompt.thread.map((msg) => ({
|
|
23356
|
-
role: msg.sender === 'assistant' ? 'assistant' : 'user',
|
|
23357
|
-
content: msg.content,
|
|
23358
|
-
}));
|
|
23359
|
-
input.push(...previousMessages);
|
|
23360
|
-
}
|
|
23361
|
-
// Add current user message
|
|
23362
|
-
input.push({
|
|
23363
|
-
role: 'user',
|
|
23364
|
-
content: rawPromptContent,
|
|
24283
|
+
async callChatModelStreamWithPreparedAgent(options) {
|
|
24284
|
+
var _a, _b, _c, _d;
|
|
24285
|
+
const { openAiAgentKitAgent, prompt, onProgress } = options;
|
|
24286
|
+
const rawPromptContent = (_a = options.rawPromptContent) !== null && _a !== void 0 ? _a : templateParameters(prompt.content, {
|
|
24287
|
+
...prompt.parameters,
|
|
24288
|
+
modelName: this.agentKitModelName,
|
|
23365
24289
|
});
|
|
23366
|
-
// Prepare tools
|
|
23367
|
-
const tools = modelRequirements.tools ? mapToolsToOpenAi(modelRequirements.tools) : undefined;
|
|
23368
|
-
// Add file_search if vector store is present
|
|
23369
|
-
const agentTools = tools ? [...tools] : [];
|
|
23370
|
-
let toolResources = undefined;
|
|
23371
|
-
if (this.vectorStoreId) {
|
|
23372
|
-
agentTools.push({ type: 'file_search' });
|
|
23373
|
-
toolResources = {
|
|
23374
|
-
file_search: {
|
|
23375
|
-
vector_store_ids: [this.vectorStoreId],
|
|
23376
|
-
},
|
|
23377
|
-
};
|
|
23378
|
-
}
|
|
23379
|
-
// Add file_search also if knowledgeSources are present in the prompt (passed via AgentLlmExecutionTools)
|
|
23380
|
-
if (modelRequirements.knowledgeSources &&
|
|
23381
|
-
modelRequirements.knowledgeSources.length > 0 &&
|
|
23382
|
-
!this.vectorStoreId) {
|
|
23383
|
-
// Note: Vector store should have been created by AgentLlmExecutionTools and passed via options.
|
|
23384
|
-
// If we are here, it means we have knowledge sources but no vector store ID.
|
|
23385
|
-
// We can't easily create one here without persisting it.
|
|
23386
|
-
console.warn('Knowledge sources provided but no vector store ID. Creating temporary vector store is not implemented in callChatModelStream.');
|
|
23387
|
-
}
|
|
23388
24290
|
const start = $getCurrentDate();
|
|
23389
|
-
|
|
24291
|
+
let latestContent = '';
|
|
24292
|
+
const toolCalls = [];
|
|
24293
|
+
const toolCallIndexById = new Map();
|
|
24294
|
+
const inputItems = await this.buildAgentKitInputItems(prompt, rawPromptContent);
|
|
23390
24295
|
const rawRequest = {
|
|
23391
|
-
|
|
23392
|
-
|
|
23393
|
-
input,
|
|
23394
|
-
instructions: modelRequirements.systemMessage,
|
|
23395
|
-
tools: agentTools.length > 0 ? agentTools : undefined,
|
|
23396
|
-
tool_resources: toolResources,
|
|
23397
|
-
store: false, // Stateless by default as we pass full history
|
|
24296
|
+
agentName: openAiAgentKitAgent.name,
|
|
24297
|
+
input: inputItems,
|
|
23398
24298
|
};
|
|
23399
|
-
|
|
23400
|
-
|
|
23401
|
-
|
|
23402
|
-
|
|
23403
|
-
|
|
23404
|
-
|
|
23405
|
-
|
|
23406
|
-
|
|
23407
|
-
|
|
23408
|
-
|
|
23409
|
-
|
|
23410
|
-
|
|
23411
|
-
|
|
23412
|
-
|
|
23413
|
-
|
|
23414
|
-
|
|
23415
|
-
|
|
23416
|
-
|
|
23417
|
-
|
|
23418
|
-
|
|
23419
|
-
|
|
23420
|
-
|
|
23421
|
-
|
|
23422
|
-
|
|
24299
|
+
const streamResult = await agents.run(openAiAgentKitAgent, inputItems, {
|
|
24300
|
+
stream: true,
|
|
24301
|
+
context: { parameters: prompt.parameters },
|
|
24302
|
+
});
|
|
24303
|
+
for await (const event of streamResult) {
|
|
24304
|
+
if (event.type === 'raw_model_stream_event' && ((_b = event.data) === null || _b === void 0 ? void 0 : _b.type) === 'output_text_delta') {
|
|
24305
|
+
latestContent += event.data.delta;
|
|
24306
|
+
onProgress({
|
|
24307
|
+
content: latestContent,
|
|
24308
|
+
modelName: this.agentKitModelName,
|
|
24309
|
+
timing: { start, complete: $getCurrentDate() },
|
|
24310
|
+
usage: UNCERTAIN_USAGE,
|
|
24311
|
+
rawPromptContent: rawPromptContent,
|
|
24312
|
+
rawRequest: null,
|
|
24313
|
+
rawResponse: {},
|
|
24314
|
+
});
|
|
24315
|
+
continue;
|
|
24316
|
+
}
|
|
24317
|
+
if (event.type === 'run_item_stream_event') {
|
|
24318
|
+
const rawItem = (_c = event.item) === null || _c === void 0 ? void 0 : _c.rawItem;
|
|
24319
|
+
if (event.name === 'tool_called' && (rawItem === null || rawItem === void 0 ? void 0 : rawItem.type) === 'function_call') {
|
|
24320
|
+
const toolCall = {
|
|
24321
|
+
name: rawItem.name,
|
|
24322
|
+
arguments: rawItem.arguments,
|
|
24323
|
+
rawToolCall: rawItem,
|
|
24324
|
+
createdAt: $getCurrentDate(),
|
|
24325
|
+
};
|
|
24326
|
+
toolCallIndexById.set(rawItem.callId, toolCalls.length);
|
|
24327
|
+
toolCalls.push(toolCall);
|
|
24328
|
+
onProgress({
|
|
24329
|
+
content: latestContent,
|
|
24330
|
+
modelName: this.agentKitModelName,
|
|
24331
|
+
timing: { start, complete: $getCurrentDate() },
|
|
24332
|
+
usage: UNCERTAIN_USAGE,
|
|
24333
|
+
rawPromptContent: rawPromptContent,
|
|
24334
|
+
rawRequest: null,
|
|
24335
|
+
rawResponse: {},
|
|
24336
|
+
toolCalls: [toolCall],
|
|
24337
|
+
});
|
|
24338
|
+
}
|
|
24339
|
+
if (event.name === 'tool_output' && (rawItem === null || rawItem === void 0 ? void 0 : rawItem.type) === 'function_call_result') {
|
|
24340
|
+
const index = toolCallIndexById.get(rawItem.callId);
|
|
24341
|
+
const result = this.formatAgentKitToolOutput(rawItem.output);
|
|
24342
|
+
if (index !== undefined) {
|
|
24343
|
+
const existingToolCall = toolCalls[index];
|
|
24344
|
+
const completedToolCall = {
|
|
24345
|
+
...existingToolCall,
|
|
24346
|
+
result,
|
|
24347
|
+
rawToolCall: rawItem,
|
|
24348
|
+
};
|
|
24349
|
+
toolCalls[index] = completedToolCall;
|
|
24350
|
+
onProgress({
|
|
24351
|
+
content: latestContent,
|
|
24352
|
+
modelName: this.agentKitModelName,
|
|
24353
|
+
timing: { start, complete: $getCurrentDate() },
|
|
24354
|
+
usage: UNCERTAIN_USAGE,
|
|
24355
|
+
rawPromptContent: rawPromptContent,
|
|
24356
|
+
rawRequest: null,
|
|
24357
|
+
rawResponse: {},
|
|
24358
|
+
toolCalls: [completedToolCall],
|
|
24359
|
+
});
|
|
23423
24360
|
}
|
|
23424
24361
|
}
|
|
23425
|
-
else if (item.type === 'function_call') ;
|
|
23426
24362
|
}
|
|
23427
24363
|
}
|
|
23428
|
-
|
|
23429
|
-
|
|
23430
|
-
|
|
23431
|
-
|
|
23432
|
-
|
|
23433
|
-
|
|
23434
|
-
content: resultContent,
|
|
23435
|
-
modelName: response.model || 'agent',
|
|
24364
|
+
await streamResult.completed;
|
|
24365
|
+
const complete = $getCurrentDate();
|
|
24366
|
+
const finalContent = ((_d = streamResult.finalOutput) !== null && _d !== void 0 ? _d : latestContent);
|
|
24367
|
+
const finalResult = {
|
|
24368
|
+
content: finalContent,
|
|
24369
|
+
modelName: this.agentKitModelName,
|
|
23436
24370
|
timing: { start, complete },
|
|
23437
24371
|
usage: UNCERTAIN_USAGE,
|
|
23438
|
-
rawPromptContent,
|
|
24372
|
+
rawPromptContent: rawPromptContent,
|
|
23439
24373
|
rawRequest,
|
|
23440
|
-
rawResponse:
|
|
23441
|
-
|
|
23442
|
-
|
|
23443
|
-
|
|
23444
|
-
|
|
23445
|
-
order: [],
|
|
23446
|
-
value: {
|
|
23447
|
-
content: resultContent,
|
|
23448
|
-
modelName: response.model || 'agent',
|
|
23449
|
-
timing: { start, complete },
|
|
23450
|
-
usage: UNCERTAIN_USAGE,
|
|
23451
|
-
rawPromptContent,
|
|
23452
|
-
rawRequest,
|
|
23453
|
-
rawResponse: response,
|
|
23454
|
-
toolCalls: toolCalls.length > 0 ? toolCalls : undefined,
|
|
23455
|
-
},
|
|
23456
|
-
});
|
|
24374
|
+
rawResponse: { runResult: streamResult },
|
|
24375
|
+
toolCalls: toolCalls.length > 0 ? toolCalls : undefined,
|
|
24376
|
+
};
|
|
24377
|
+
onProgress(finalResult);
|
|
24378
|
+
return finalResult;
|
|
23457
24379
|
}
|
|
23458
24380
|
/**
|
|
23459
|
-
*
|
|
24381
|
+
* Builds AgentKit input items from the prompt and optional thread.
|
|
23460
24382
|
*/
|
|
23461
|
-
|
|
23462
|
-
|
|
23463
|
-
const
|
|
23464
|
-
|
|
23465
|
-
|
|
23466
|
-
|
|
23467
|
-
|
|
23468
|
-
|
|
23469
|
-
|
|
23470
|
-
|
|
23471
|
-
|
|
23472
|
-
|
|
23473
|
-
|
|
23474
|
-
const response = await fetch(source);
|
|
23475
|
-
if (!response.ok) {
|
|
23476
|
-
console.error(`Failed to download ${source}: ${response.statusText}`);
|
|
23477
|
-
continue;
|
|
23478
|
-
}
|
|
23479
|
-
const buffer = await response.arrayBuffer();
|
|
23480
|
-
const filename = source.split('/').pop() || 'downloaded-file';
|
|
23481
|
-
const blob = new Blob([buffer]);
|
|
23482
|
-
const file = new File([blob], filename);
|
|
23483
|
-
fileStreams.push(file);
|
|
24383
|
+
async buildAgentKitInputItems(prompt, rawPromptContent) {
|
|
24384
|
+
var _a;
|
|
24385
|
+
const inputItems = [];
|
|
24386
|
+
if ('thread' in prompt && Array.isArray(prompt.thread)) {
|
|
24387
|
+
for (const message of prompt.thread) {
|
|
24388
|
+
const sender = message.sender;
|
|
24389
|
+
const content = (_a = message.content) !== null && _a !== void 0 ? _a : '';
|
|
24390
|
+
if (sender === 'assistant' || sender === 'agent') {
|
|
24391
|
+
inputItems.push({
|
|
24392
|
+
role: 'assistant',
|
|
24393
|
+
status: 'completed',
|
|
24394
|
+
content: [{ type: 'output_text', text: content }],
|
|
24395
|
+
});
|
|
23484
24396
|
}
|
|
23485
24397
|
else {
|
|
23486
|
-
|
|
24398
|
+
inputItems.push({
|
|
24399
|
+
role: 'user',
|
|
24400
|
+
content,
|
|
24401
|
+
});
|
|
23487
24402
|
}
|
|
23488
24403
|
}
|
|
23489
|
-
catch (error) {
|
|
23490
|
-
console.error(`Error processing knowledge source ${source}:`, error);
|
|
23491
|
-
}
|
|
23492
24404
|
}
|
|
23493
|
-
|
|
23494
|
-
|
|
23495
|
-
|
|
23496
|
-
|
|
23497
|
-
|
|
23498
|
-
|
|
23499
|
-
|
|
23500
|
-
|
|
23501
|
-
|
|
24405
|
+
const userContent = await this.buildAgentKitUserContent(prompt, rawPromptContent);
|
|
24406
|
+
inputItems.push({
|
|
24407
|
+
role: 'user',
|
|
24408
|
+
content: userContent,
|
|
24409
|
+
});
|
|
24410
|
+
return inputItems;
|
|
24411
|
+
}
|
|
24412
|
+
/**
|
|
24413
|
+
* Builds the user message content for AgentKit runs, including file inputs when provided.
|
|
24414
|
+
*/
|
|
24415
|
+
async buildAgentKitUserContent(prompt, rawPromptContent) {
|
|
24416
|
+
if ('files' in prompt && Array.isArray(prompt.files) && prompt.files.length > 0) {
|
|
24417
|
+
const fileItems = await Promise.all(prompt.files.map(async (file) => {
|
|
24418
|
+
const arrayBuffer = await file.arrayBuffer();
|
|
24419
|
+
const base64 = Buffer.from(arrayBuffer).toString('base64');
|
|
24420
|
+
return {
|
|
24421
|
+
type: 'input_image',
|
|
24422
|
+
image: `data:${file.type};base64,${base64}`,
|
|
24423
|
+
};
|
|
24424
|
+
}));
|
|
24425
|
+
return [{ type: 'input_text', text: rawPromptContent }, ...fileItems];
|
|
24426
|
+
}
|
|
24427
|
+
return rawPromptContent;
|
|
24428
|
+
}
|
|
24429
|
+
/**
|
|
24430
|
+
* Normalizes AgentKit tool outputs into a string for Promptbook tool call results.
|
|
24431
|
+
*/
|
|
24432
|
+
formatAgentKitToolOutput(output) {
|
|
24433
|
+
if (typeof output === 'string') {
|
|
24434
|
+
return output;
|
|
24435
|
+
}
|
|
24436
|
+
if (output && typeof output === 'object') {
|
|
24437
|
+
const textOutput = output;
|
|
24438
|
+
if (textOutput.type === 'text' && typeof textOutput.text === 'string') {
|
|
24439
|
+
return textOutput.text;
|
|
23502
24440
|
}
|
|
23503
24441
|
}
|
|
23504
|
-
return
|
|
24442
|
+
return JSON.stringify(output !== null && output !== void 0 ? output : null);
|
|
23505
24443
|
}
|
|
23506
24444
|
/**
|
|
23507
|
-
*
|
|
24445
|
+
* Returns AgentKit-specific options.
|
|
24446
|
+
*/
|
|
24447
|
+
get agentKitOptions() {
|
|
24448
|
+
return this.options;
|
|
24449
|
+
}
|
|
24450
|
+
/**
|
|
24451
|
+
* Discriminant for type guards.
|
|
23508
24452
|
*/
|
|
23509
24453
|
get discriminant() {
|
|
23510
|
-
return
|
|
24454
|
+
return DISCRIMINANT$1;
|
|
23511
24455
|
}
|
|
23512
24456
|
/**
|
|
23513
|
-
* Type guard to check if given `LlmExecutionTools` are instanceof `
|
|
24457
|
+
* Type guard to check if given `LlmExecutionTools` are instanceof `OpenAiAgentKitExecutionTools`.
|
|
23514
24458
|
*/
|
|
23515
|
-
static
|
|
23516
|
-
return llmExecutionTools.discriminant ===
|
|
24459
|
+
static isOpenAiAgentKitExecutionTools(llmExecutionTools) {
|
|
24460
|
+
return llmExecutionTools.discriminant === DISCRIMINANT$1;
|
|
23517
24461
|
}
|
|
23518
24462
|
}
|
|
24463
|
+
/**
|
|
24464
|
+
* Discriminant for type guards.
|
|
24465
|
+
*
|
|
24466
|
+
* @private const of `OpenAiAgentKitExecutionTools`
|
|
24467
|
+
*/
|
|
24468
|
+
const DISCRIMINANT$1 = 'OPEN_AI_AGENT_KIT_V1';
|
|
23519
24469
|
|
|
23520
24470
|
/**
|
|
23521
24471
|
* Uploads files to OpenAI and returns their IDs
|
|
@@ -23550,10 +24500,10 @@
|
|
|
23550
24500
|
* - `OpenAiAssistantExecutionTools` - which is a specific implementation of `LlmExecutionTools` for OpenAI models with assistant capabilities, recommended for usage in `Agent` or `AgentLlmExecutionTools`
|
|
23551
24501
|
* - `RemoteAgent` - which is an `Agent` that connects to a Promptbook Agents Server
|
|
23552
24502
|
*
|
|
24503
|
+
* @deprecated Use `OpenAiAgentKitExecutionTools` instead.
|
|
23553
24504
|
* @public exported from `@promptbook/openai`
|
|
23554
|
-
* @deprecated Use `OpenAiAgentExecutionTools` instead which uses the new OpenAI Responses API
|
|
23555
24505
|
*/
|
|
23556
|
-
class OpenAiAssistantExecutionTools extends
|
|
24506
|
+
class OpenAiAssistantExecutionTools extends OpenAiVectorStoreHandler {
|
|
23557
24507
|
/**
|
|
23558
24508
|
* Creates OpenAI Execution Tools.
|
|
23559
24509
|
*
|
|
@@ -23682,8 +24632,7 @@
|
|
|
23682
24632
|
console.info(colors__default["default"].bgWhite('rawRequest (non-streaming with tools)'), JSON.stringify(rawRequest, null, 4));
|
|
23683
24633
|
}
|
|
23684
24634
|
// Create thread and run
|
|
23685
|
-
|
|
23686
|
-
let run = threadAndRun;
|
|
24635
|
+
let run = (await client.beta.threads.createAndRun(rawRequest));
|
|
23687
24636
|
const completedToolCalls = [];
|
|
23688
24637
|
const toolCallStartedAt = new Map();
|
|
23689
24638
|
// Poll until run completes or requires action
|
|
@@ -23778,14 +24727,14 @@
|
|
|
23778
24727
|
}
|
|
23779
24728
|
}
|
|
23780
24729
|
// Submit tool outputs
|
|
23781
|
-
run = await client.beta.threads.runs.submitToolOutputs(run.thread_id, run.id, {
|
|
24730
|
+
run = (await client.beta.threads.runs.submitToolOutputs(run.thread_id, run.id, {
|
|
23782
24731
|
tool_outputs: toolOutputs,
|
|
23783
|
-
});
|
|
24732
|
+
}));
|
|
23784
24733
|
}
|
|
23785
24734
|
else {
|
|
23786
24735
|
// Wait a bit before polling again
|
|
23787
24736
|
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
23788
|
-
run = await client.beta.threads.runs.retrieve(run.thread_id, run.id);
|
|
24737
|
+
run = (await client.beta.threads.runs.retrieve(run.thread_id, run.id));
|
|
23789
24738
|
}
|
|
23790
24739
|
}
|
|
23791
24740
|
if (run.status !== 'completed') {
|
|
@@ -24010,88 +24959,13 @@
|
|
|
24010
24959
|
let vectorStoreId;
|
|
24011
24960
|
// If knowledge sources are provided, create a vector store with them
|
|
24012
24961
|
if (knowledgeSources && knowledgeSources.length > 0) {
|
|
24013
|
-
|
|
24014
|
-
|
|
24015
|
-
|
|
24016
|
-
|
|
24017
|
-
|
|
24018
|
-
}
|
|
24019
|
-
// Create a vector store
|
|
24020
|
-
const vectorStore = await client.beta.vectorStores.create({
|
|
24021
|
-
name: `${name} Knowledge Base`,
|
|
24962
|
+
const vectorStoreResult = await this.createVectorStoreWithKnowledgeSources({
|
|
24963
|
+
client,
|
|
24964
|
+
name,
|
|
24965
|
+
knowledgeSources,
|
|
24966
|
+
logLabel: 'assistant creation',
|
|
24022
24967
|
});
|
|
24023
|
-
vectorStoreId =
|
|
24024
|
-
if (this.options.isVerbose) {
|
|
24025
|
-
console.info('[🤰]', 'Vector store created', {
|
|
24026
|
-
vectorStoreId,
|
|
24027
|
-
});
|
|
24028
|
-
}
|
|
24029
|
-
// Upload files from knowledge sources to the vector store
|
|
24030
|
-
const fileStreams = [];
|
|
24031
|
-
for (const [index, source] of knowledgeSources.entries()) {
|
|
24032
|
-
try {
|
|
24033
|
-
if (this.options.isVerbose) {
|
|
24034
|
-
console.info('[🤰]', 'Processing knowledge source', {
|
|
24035
|
-
index: index + 1,
|
|
24036
|
-
total: knowledgeSources.length,
|
|
24037
|
-
source,
|
|
24038
|
-
sourceType: source.startsWith('http') || source.startsWith('https') ? 'url' : 'file',
|
|
24039
|
-
});
|
|
24040
|
-
}
|
|
24041
|
-
// Check if it's a URL
|
|
24042
|
-
if (source.startsWith('http://') || source.startsWith('https://')) {
|
|
24043
|
-
// Download the file
|
|
24044
|
-
const response = await fetch(source);
|
|
24045
|
-
if (!response.ok) {
|
|
24046
|
-
console.error(`Failed to download ${source}: ${response.statusText}`);
|
|
24047
|
-
continue;
|
|
24048
|
-
}
|
|
24049
|
-
const buffer = await response.arrayBuffer();
|
|
24050
|
-
let filename = source.split('/').pop() || 'downloaded-file';
|
|
24051
|
-
try {
|
|
24052
|
-
const url = new URL(source);
|
|
24053
|
-
filename = url.pathname.split('/').pop() || filename;
|
|
24054
|
-
}
|
|
24055
|
-
catch (error) {
|
|
24056
|
-
// Keep default filename
|
|
24057
|
-
}
|
|
24058
|
-
const blob = new Blob([buffer]);
|
|
24059
|
-
const file = new File([blob], filename);
|
|
24060
|
-
fileStreams.push(file);
|
|
24061
|
-
}
|
|
24062
|
-
else {
|
|
24063
|
-
/*
|
|
24064
|
-
TODO: [🐱🚀] Resolve problem with browser environment
|
|
24065
|
-
// Assume it's a local file path
|
|
24066
|
-
// Note: This will work in Node.js environment
|
|
24067
|
-
// For browser environments, this would need different handling
|
|
24068
|
-
const fs = await import('fs');
|
|
24069
|
-
const fileStream = fs.createReadStream(source);
|
|
24070
|
-
fileStreams.push(fileStream);
|
|
24071
|
-
*/
|
|
24072
|
-
}
|
|
24073
|
-
}
|
|
24074
|
-
catch (error) {
|
|
24075
|
-
console.error(`Error processing knowledge source ${source}:`, error);
|
|
24076
|
-
}
|
|
24077
|
-
}
|
|
24078
|
-
// Batch upload files to the vector store
|
|
24079
|
-
if (fileStreams.length > 0) {
|
|
24080
|
-
try {
|
|
24081
|
-
await client.beta.vectorStores.fileBatches.uploadAndPoll(vectorStoreId, {
|
|
24082
|
-
files: fileStreams,
|
|
24083
|
-
});
|
|
24084
|
-
if (this.options.isVerbose) {
|
|
24085
|
-
console.info('[🤰]', 'Uploaded files to vector store', {
|
|
24086
|
-
vectorStoreId,
|
|
24087
|
-
fileCount: fileStreams.length,
|
|
24088
|
-
});
|
|
24089
|
-
}
|
|
24090
|
-
}
|
|
24091
|
-
catch (error) {
|
|
24092
|
-
console.error('Error uploading files to vector store:', error);
|
|
24093
|
-
}
|
|
24094
|
-
}
|
|
24968
|
+
vectorStoreId = vectorStoreResult.vectorStoreId;
|
|
24095
24969
|
}
|
|
24096
24970
|
// Create assistant with vector store attached
|
|
24097
24971
|
const assistantConfig = {
|
|
@@ -24158,91 +25032,14 @@
|
|
|
24158
25032
|
const client = await this.getClient();
|
|
24159
25033
|
let vectorStoreId;
|
|
24160
25034
|
// If knowledge sources are provided, create a vector store with them
|
|
24161
|
-
// TODO: [🧠] Reuse vector store creation logic from createNewAssistant
|
|
24162
25035
|
if (knowledgeSources && knowledgeSources.length > 0) {
|
|
24163
|
-
|
|
24164
|
-
|
|
24165
|
-
|
|
24166
|
-
|
|
24167
|
-
|
|
24168
|
-
});
|
|
24169
|
-
}
|
|
24170
|
-
// Create a vector store
|
|
24171
|
-
const vectorStore = await client.beta.vectorStores.create({
|
|
24172
|
-
name: `${name} Knowledge Base`,
|
|
25036
|
+
const vectorStoreResult = await this.createVectorStoreWithKnowledgeSources({
|
|
25037
|
+
client,
|
|
25038
|
+
name: name !== null && name !== void 0 ? name : assistantId,
|
|
25039
|
+
knowledgeSources,
|
|
25040
|
+
logLabel: 'assistant update',
|
|
24173
25041
|
});
|
|
24174
|
-
vectorStoreId =
|
|
24175
|
-
if (this.options.isVerbose) {
|
|
24176
|
-
console.info('[🤰]', 'Vector store created for assistant update', {
|
|
24177
|
-
vectorStoreId,
|
|
24178
|
-
});
|
|
24179
|
-
}
|
|
24180
|
-
// Upload files from knowledge sources to the vector store
|
|
24181
|
-
const fileStreams = [];
|
|
24182
|
-
for (const [index, source] of knowledgeSources.entries()) {
|
|
24183
|
-
try {
|
|
24184
|
-
if (this.options.isVerbose) {
|
|
24185
|
-
console.info('[🤰]', 'Processing knowledge source for update', {
|
|
24186
|
-
index: index + 1,
|
|
24187
|
-
total: knowledgeSources.length,
|
|
24188
|
-
source,
|
|
24189
|
-
sourceType: source.startsWith('http') || source.startsWith('https') ? 'url' : 'file',
|
|
24190
|
-
});
|
|
24191
|
-
}
|
|
24192
|
-
// Check if it's a URL
|
|
24193
|
-
if (source.startsWith('http://') || source.startsWith('https://')) {
|
|
24194
|
-
// Download the file
|
|
24195
|
-
const response = await fetch(source);
|
|
24196
|
-
if (!response.ok) {
|
|
24197
|
-
console.error(`Failed to download ${source}: ${response.statusText}`);
|
|
24198
|
-
continue;
|
|
24199
|
-
}
|
|
24200
|
-
const buffer = await response.arrayBuffer();
|
|
24201
|
-
let filename = source.split('/').pop() || 'downloaded-file';
|
|
24202
|
-
try {
|
|
24203
|
-
const url = new URL(source);
|
|
24204
|
-
filename = url.pathname.split('/').pop() || filename;
|
|
24205
|
-
}
|
|
24206
|
-
catch (error) {
|
|
24207
|
-
// Keep default filename
|
|
24208
|
-
}
|
|
24209
|
-
const blob = new Blob([buffer]);
|
|
24210
|
-
const file = new File([blob], filename);
|
|
24211
|
-
fileStreams.push(file);
|
|
24212
|
-
}
|
|
24213
|
-
else {
|
|
24214
|
-
/*
|
|
24215
|
-
TODO: [🐱🚀] Resolve problem with browser environment
|
|
24216
|
-
// Assume it's a local file path
|
|
24217
|
-
// Note: This will work in Node.js environment
|
|
24218
|
-
// For browser environments, this would need different handling
|
|
24219
|
-
const fs = await import('fs');
|
|
24220
|
-
const fileStream = fs.createReadStream(source);
|
|
24221
|
-
fileStreams.push(fileStream);
|
|
24222
|
-
*/
|
|
24223
|
-
}
|
|
24224
|
-
}
|
|
24225
|
-
catch (error) {
|
|
24226
|
-
console.error(`Error processing knowledge source ${source}:`, error);
|
|
24227
|
-
}
|
|
24228
|
-
}
|
|
24229
|
-
// Batch upload files to the vector store
|
|
24230
|
-
if (fileStreams.length > 0) {
|
|
24231
|
-
try {
|
|
24232
|
-
await client.beta.vectorStores.fileBatches.uploadAndPoll(vectorStoreId, {
|
|
24233
|
-
files: fileStreams,
|
|
24234
|
-
});
|
|
24235
|
-
if (this.options.isVerbose) {
|
|
24236
|
-
console.info('[🤰]', 'Uploaded files to vector store for update', {
|
|
24237
|
-
vectorStoreId,
|
|
24238
|
-
fileCount: fileStreams.length,
|
|
24239
|
-
});
|
|
24240
|
-
}
|
|
24241
|
-
}
|
|
24242
|
-
catch (error) {
|
|
24243
|
-
console.error('Error uploading files to vector store:', error);
|
|
24244
|
-
}
|
|
24245
|
-
}
|
|
25042
|
+
vectorStoreId = vectorStoreResult.vectorStoreId;
|
|
24246
25043
|
}
|
|
24247
25044
|
const assistantUpdate = {
|
|
24248
25045
|
name,
|
|
@@ -24346,8 +25143,8 @@
|
|
|
24346
25143
|
* - `Agent` - which represents an AI Agent with its source, memories, actions, etc. Agent is a higher-level abstraction which is internally using:
|
|
24347
25144
|
* - `LlmExecutionTools` - which wraps one or more LLM models and provides an interface to execute them
|
|
24348
25145
|
* - `AgentLlmExecutionTools` - which is a specific implementation of `LlmExecutionTools` that wraps another LlmExecutionTools and applies agent-specific system prompts and requirements
|
|
24349
|
-
* - `OpenAiAgentExecutionTools` - which is a specific implementation of `LlmExecutionTools` for OpenAI models with agent capabilities (using Responses API), recommended for usage in `Agent` or `AgentLlmExecutionTools`
|
|
24350
25146
|
* - `OpenAiAssistantExecutionTools` - (Deprecated) which is a specific implementation of `LlmExecutionTools` for OpenAI models with assistant capabilities
|
|
25147
|
+
* - `OpenAiAgentKitExecutionTools` - which is a specific implementation of `LlmExecutionTools` backed by OpenAI AgentKit
|
|
24351
25148
|
* - `RemoteAgent` - which is an `Agent` that connects to a Promptbook Agents Server
|
|
24352
25149
|
*
|
|
24353
25150
|
* @public exported from `@promptbook/core`
|
|
@@ -24482,6 +25279,7 @@
|
|
|
24482
25279
|
* Calls the chat model with agent-specific system prompt and requirements with streaming
|
|
24483
25280
|
*/
|
|
24484
25281
|
async callChatModelStream(prompt, onProgress) {
|
|
25282
|
+
var _a, _b;
|
|
24485
25283
|
// Ensure we're working with a chat prompt
|
|
24486
25284
|
if (prompt.modelRequirements.modelVariant !== 'CHAT') {
|
|
24487
25285
|
throw new Error('AgentLlmExecutionTools only supports chat prompts');
|
|
@@ -24509,63 +25307,73 @@
|
|
|
24509
25307
|
}, // Cast to avoid readonly mismatch from spread
|
|
24510
25308
|
};
|
|
24511
25309
|
console.log('!!!! promptWithAgentModelRequirements:', promptWithAgentModelRequirements);
|
|
24512
|
-
if (
|
|
25310
|
+
if (OpenAiAgentKitExecutionTools.isOpenAiAgentKitExecutionTools(this.options.llmTools)) {
|
|
24513
25311
|
const requirementsHash = cryptoJs.SHA256(JSON.stringify(modelRequirements)).toString();
|
|
24514
|
-
const
|
|
24515
|
-
|
|
24516
|
-
|
|
25312
|
+
const vectorStoreHash = cryptoJs.SHA256(JSON.stringify((_a = modelRequirements.knowledgeSources) !== null && _a !== void 0 ? _a : [])).toString();
|
|
25313
|
+
const cachedVectorStore = AgentLlmExecutionTools.vectorStoreCache.get(this.title);
|
|
25314
|
+
const cachedAgentKit = AgentLlmExecutionTools.agentKitAgentCache.get(this.title);
|
|
25315
|
+
let preparedAgentKit = this.options.assistantPreparationMode === 'external'
|
|
25316
|
+
? this.options.llmTools.getPreparedAgentKitAgent()
|
|
25317
|
+
: null;
|
|
25318
|
+
const vectorStoreId = (preparedAgentKit === null || preparedAgentKit === void 0 ? void 0 : preparedAgentKit.vectorStoreId) ||
|
|
25319
|
+
(cachedVectorStore && cachedVectorStore.requirementsHash === vectorStoreHash
|
|
25320
|
+
? cachedVectorStore.vectorStoreId
|
|
25321
|
+
: undefined);
|
|
25322
|
+
if (!preparedAgentKit && cachedAgentKit && cachedAgentKit.requirementsHash === requirementsHash) {
|
|
24517
25323
|
if (this.options.isVerbose) {
|
|
24518
|
-
console.
|
|
25324
|
+
console.info('[🤰]', 'Using cached OpenAI AgentKit agent', {
|
|
25325
|
+
agent: this.title,
|
|
25326
|
+
});
|
|
24519
25327
|
}
|
|
24520
|
-
|
|
24521
|
-
|
|
24522
|
-
|
|
24523
|
-
|
|
24524
|
-
// We can cast to access options if they were public, or use a method to clone.
|
|
24525
|
-
// OpenAiAgentExecutionTools doesn't have a clone method.
|
|
24526
|
-
// However, we can just assume the passed tool *might* not have the vector store yet, or we are replacing it.
|
|
24527
|
-
// Actually, if the passed tool IS OpenAiAgentExecutionTools, we should use it as a base.
|
|
24528
|
-
// TODO: [🧠] This is a bit hacky, accessing protected options or recreating tools.
|
|
24529
|
-
// Ideally OpenAiAgentExecutionTools should have a method `withVectorStoreId`.
|
|
24530
|
-
agentTools = new OpenAiAgentExecutionTools({
|
|
24531
|
-
...this.options.llmTools.options,
|
|
24532
|
-
vectorStoreId: cached.vectorStoreId,
|
|
24533
|
-
});
|
|
25328
|
+
preparedAgentKit = {
|
|
25329
|
+
agent: cachedAgentKit.agent,
|
|
25330
|
+
vectorStoreId: cachedAgentKit.vectorStoreId,
|
|
25331
|
+
};
|
|
24534
25332
|
}
|
|
24535
|
-
|
|
25333
|
+
if (!preparedAgentKit) {
|
|
24536
25334
|
if (this.options.isVerbose) {
|
|
24537
|
-
console.
|
|
24538
|
-
|
|
24539
|
-
|
|
24540
|
-
if (modelRequirements.knowledgeSources && modelRequirements.knowledgeSources.length > 0) {
|
|
24541
|
-
const client = await this.options.llmTools.getClient();
|
|
24542
|
-
vectorStoreId = await OpenAiAgentExecutionTools.createVectorStore(client, this.title, modelRequirements.knowledgeSources);
|
|
25335
|
+
console.info('[🤰]', 'Preparing OpenAI AgentKit agent', {
|
|
25336
|
+
agent: this.title,
|
|
25337
|
+
});
|
|
24543
25338
|
}
|
|
24544
|
-
if (vectorStoreId) {
|
|
24545
|
-
|
|
24546
|
-
|
|
24547
|
-
|
|
25339
|
+
if (!vectorStoreId && ((_b = modelRequirements.knowledgeSources) === null || _b === void 0 ? void 0 : _b.length)) {
|
|
25340
|
+
emitAssistantPreparationProgress({
|
|
25341
|
+
onProgress,
|
|
25342
|
+
prompt,
|
|
25343
|
+
modelName: this.modelName,
|
|
25344
|
+
phase: 'Creating knowledge base',
|
|
24548
25345
|
});
|
|
24549
25346
|
}
|
|
24550
|
-
|
|
24551
|
-
|
|
25347
|
+
emitAssistantPreparationProgress({
|
|
25348
|
+
onProgress,
|
|
25349
|
+
prompt,
|
|
25350
|
+
modelName: this.modelName,
|
|
25351
|
+
phase: 'Preparing AgentKit agent',
|
|
25352
|
+
});
|
|
25353
|
+
preparedAgentKit = await this.options.llmTools.prepareAgentKitAgent({
|
|
25354
|
+
name: this.title,
|
|
25355
|
+
instructions: modelRequirements.systemMessage || '',
|
|
25356
|
+
knowledgeSources: modelRequirements.knowledgeSources,
|
|
25357
|
+
tools: modelRequirements.tools ? [...modelRequirements.tools] : undefined,
|
|
24552
25358
|
vectorStoreId,
|
|
24553
25359
|
});
|
|
24554
25360
|
}
|
|
24555
|
-
|
|
24556
|
-
|
|
24557
|
-
|
|
24558
|
-
|
|
24559
|
-
|
|
24560
|
-
|
|
24561
|
-
|
|
24562
|
-
|
|
24563
|
-
|
|
24564
|
-
|
|
24565
|
-
|
|
24566
|
-
|
|
24567
|
-
|
|
24568
|
-
|
|
25361
|
+
if (preparedAgentKit.vectorStoreId) {
|
|
25362
|
+
AgentLlmExecutionTools.vectorStoreCache.set(this.title, {
|
|
25363
|
+
vectorStoreId: preparedAgentKit.vectorStoreId,
|
|
25364
|
+
requirementsHash: vectorStoreHash,
|
|
25365
|
+
});
|
|
25366
|
+
}
|
|
25367
|
+
AgentLlmExecutionTools.agentKitAgentCache.set(this.title, {
|
|
25368
|
+
agent: preparedAgentKit.agent,
|
|
25369
|
+
requirementsHash,
|
|
25370
|
+
vectorStoreId: preparedAgentKit.vectorStoreId,
|
|
25371
|
+
});
|
|
25372
|
+
underlyingLlmResult = await this.options.llmTools.callChatModelStreamWithPreparedAgent({
|
|
25373
|
+
openAiAgentKitAgent: preparedAgentKit.agent,
|
|
25374
|
+
prompt: promptWithAgentModelRequirements,
|
|
25375
|
+
onProgress,
|
|
25376
|
+
});
|
|
24569
25377
|
}
|
|
24570
25378
|
else if (OpenAiAssistantExecutionTools.isOpenAiAssistantExecutionTools(this.options.llmTools)) {
|
|
24571
25379
|
// ... deprecated path ...
|
|
@@ -24692,6 +25500,10 @@
|
|
|
24692
25500
|
return agentResult;
|
|
24693
25501
|
}
|
|
24694
25502
|
}
|
|
25503
|
+
/**
|
|
25504
|
+
* Cached AgentKit agents to avoid rebuilding identical instances.
|
|
25505
|
+
*/
|
|
25506
|
+
AgentLlmExecutionTools.agentKitAgentCache = new Map();
|
|
24695
25507
|
/**
|
|
24696
25508
|
* Cache of OpenAI assistants to avoid creating duplicates
|
|
24697
25509
|
*/
|
|
@@ -24772,8 +25584,8 @@
|
|
|
24772
25584
|
* - `Agent` - which represents an AI Agent with its source, memories, actions, etc. Agent is a higher-level abstraction which is internally using:
|
|
24773
25585
|
* - `LlmExecutionTools` - which wraps one or more LLM models and provides an interface to execute them
|
|
24774
25586
|
* - `AgentLlmExecutionTools` - which is a specific implementation of `LlmExecutionTools` that wraps another LlmExecutionTools and applies agent-specific system prompts and requirements
|
|
24775
|
-
* - `OpenAiAgentExecutionTools` - which is a specific implementation of `LlmExecutionTools` for OpenAI models with agent capabilities (using Responses API), recommended for usage in `Agent` or `AgentLlmExecutionTools`
|
|
24776
25587
|
* - `OpenAiAssistantExecutionTools` - (Deprecated) which is a specific implementation of `LlmExecutionTools` for OpenAI models with assistant capabilities
|
|
25588
|
+
* - `OpenAiAgentKitExecutionTools` - which is a specific implementation of `LlmExecutionTools` backed by OpenAI AgentKit
|
|
24777
25589
|
* - `RemoteAgent` - which is an `Agent` that connects to a Promptbook Agents Server
|
|
24778
25590
|
*
|
|
24779
25591
|
* @public exported from `@promptbook/core`
|
|
@@ -25144,7 +25956,8 @@
|
|
|
25144
25956
|
* - `Agent` - which represents an AI Agent with its source, memories, actions, etc. Agent is a higher-level abstraction which is internally using:
|
|
25145
25957
|
* - `LlmExecutionTools` - which wraps one or more LLM models and provides an interface to execute them
|
|
25146
25958
|
* - `AgentLlmExecutionTools` - which is a specific implementation of `LlmExecutionTools` that wraps another LlmExecutionTools and applies agent-specific system prompts and requirements
|
|
25147
|
-
* - `OpenAiAssistantExecutionTools` - which is a specific implementation of `LlmExecutionTools` for OpenAI models with assistant capabilities
|
|
25959
|
+
* - `OpenAiAssistantExecutionTools` - (Deprecated) which is a specific implementation of `LlmExecutionTools` for OpenAI models with assistant capabilities
|
|
25960
|
+
* - `OpenAiAgentKitExecutionTools` - which is a specific implementation of `LlmExecutionTools` backed by OpenAI AgentKit
|
|
25148
25961
|
* - `RemoteAgent` - which is an `Agent` that connects to a Promptbook Agents Server
|
|
25149
25962
|
*
|
|
25150
25963
|
* @public exported from `@promptbook/core`
|