@promptbook/cli 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 +1200 -386
- 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 +6 -2
- package/umd/index.umd.js +1203 -390
- 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
|
@@ -31,6 +31,7 @@ import { OpenAIClient, AzureKeyCredential } from '@azure/openai';
|
|
|
31
31
|
import { Subject, BehaviorSubject } from 'rxjs';
|
|
32
32
|
import { lookup, extension } from 'mime-types';
|
|
33
33
|
import { parse, unparse } from 'papaparse';
|
|
34
|
+
import { Agent as Agent$1, setDefaultOpenAIClient, setDefaultOpenAIKey, fileSearchTool, tool, run } from '@openai/agents';
|
|
34
35
|
import OpenAI from 'openai';
|
|
35
36
|
|
|
36
37
|
// ⚠️ WARNING: This code has been generated so that any manual changes will be overwritten
|
|
@@ -47,7 +48,7 @@ const BOOK_LANGUAGE_VERSION = '2.0.0';
|
|
|
47
48
|
* @generated
|
|
48
49
|
* @see https://github.com/webgptorg/promptbook
|
|
49
50
|
*/
|
|
50
|
-
const PROMPTBOOK_ENGINE_VERSION = '0.110.0-
|
|
51
|
+
const PROMPTBOOK_ENGINE_VERSION = '0.110.0-7';
|
|
51
52
|
/**
|
|
52
53
|
* TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
|
|
53
54
|
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
@@ -27028,16 +27029,11 @@ class OpenAiCompatibleExecutionTools {
|
|
|
27028
27029
|
const openAiOptions = { ...this.options };
|
|
27029
27030
|
delete openAiOptions.isVerbose;
|
|
27030
27031
|
delete openAiOptions.userId;
|
|
27031
|
-
// Enhanced configuration
|
|
27032
|
+
// Enhanced configuration with retries and timeouts.
|
|
27032
27033
|
const enhancedOptions = {
|
|
27033
27034
|
...openAiOptions,
|
|
27034
27035
|
timeout: API_REQUEST_TIMEOUT,
|
|
27035
27036
|
maxRetries: CONNECTION_RETRIES_LIMIT,
|
|
27036
|
-
defaultHeaders: {
|
|
27037
|
-
Connection: 'keep-alive',
|
|
27038
|
-
'Keep-Alive': 'timeout=30, max=100',
|
|
27039
|
-
...openAiOptions.defaultHeaders,
|
|
27040
|
-
},
|
|
27041
27037
|
};
|
|
27042
27038
|
this.client = new OpenAI(enhancedOptions);
|
|
27043
27039
|
}
|
|
@@ -28423,18 +28419,6 @@ class OpenAiExecutionTools extends OpenAiCompatibleExecutionTools {
|
|
|
28423
28419
|
get profile() {
|
|
28424
28420
|
return OPENAI_PROVIDER_PROFILE;
|
|
28425
28421
|
}
|
|
28426
|
-
/*
|
|
28427
|
-
Note: Commenting this out to avoid circular dependency
|
|
28428
|
-
/**
|
|
28429
|
-
* Create (sub)tools for calling OpenAI API Assistants
|
|
28430
|
-
*
|
|
28431
|
-
* @param assistantId Which assistant to use
|
|
28432
|
-
* @returns Tools for calling OpenAI API Assistants with same token
|
|
28433
|
-
* /
|
|
28434
|
-
public createAssistantSubtools(assistantId: string_token): OpenAiAssistantExecutionTools {
|
|
28435
|
-
return new OpenAiAssistantExecutionTools({ ...this.options, assistantId });
|
|
28436
|
-
}
|
|
28437
|
-
*/
|
|
28438
28422
|
/**
|
|
28439
28423
|
* List all available models (non dynamically)
|
|
28440
28424
|
*
|
|
@@ -28469,6 +28453,754 @@ class OpenAiExecutionTools extends OpenAiCompatibleExecutionTools {
|
|
|
28469
28453
|
}
|
|
28470
28454
|
}
|
|
28471
28455
|
|
|
28456
|
+
const DEFAULT_KNOWLEDGE_SOURCE_DOWNLOAD_TIMEOUT_MS = 30000;
|
|
28457
|
+
const DEFAULT_KNOWLEDGE_SOURCE_UPLOAD_TIMEOUT_MS = 900000;
|
|
28458
|
+
const VECTOR_STORE_PROGRESS_LOG_INTERVAL_MIN_MS = 15000;
|
|
28459
|
+
const VECTOR_STORE_STALL_LOG_THRESHOLD_MS = 30000;
|
|
28460
|
+
/**
|
|
28461
|
+
* Base class for OpenAI execution tools that need hosted vector stores.
|
|
28462
|
+
*
|
|
28463
|
+
* @public exported from `@promptbook/openai`
|
|
28464
|
+
*/
|
|
28465
|
+
class OpenAiVectorStoreHandler extends OpenAiExecutionTools {
|
|
28466
|
+
/**
|
|
28467
|
+
* Returns the per-knowledge-source download timeout in milliseconds.
|
|
28468
|
+
*/
|
|
28469
|
+
getKnowledgeSourceDownloadTimeoutMs() {
|
|
28470
|
+
var _a;
|
|
28471
|
+
return (_a = this.vectorStoreOptions.knowledgeSourceDownloadTimeoutMs) !== null && _a !== void 0 ? _a : DEFAULT_KNOWLEDGE_SOURCE_DOWNLOAD_TIMEOUT_MS;
|
|
28472
|
+
}
|
|
28473
|
+
/**
|
|
28474
|
+
* Returns the max concurrency for knowledge source uploads.
|
|
28475
|
+
*/
|
|
28476
|
+
getKnowledgeSourceUploadMaxConcurrency() {
|
|
28477
|
+
var _a;
|
|
28478
|
+
return (_a = this.vectorStoreOptions.knowledgeSourceUploadMaxConcurrency) !== null && _a !== void 0 ? _a : 5;
|
|
28479
|
+
}
|
|
28480
|
+
/**
|
|
28481
|
+
* Returns the polling interval in milliseconds for vector store uploads.
|
|
28482
|
+
*/
|
|
28483
|
+
getKnowledgeSourceUploadPollIntervalMs() {
|
|
28484
|
+
var _a;
|
|
28485
|
+
return (_a = this.vectorStoreOptions.knowledgeSourceUploadPollIntervalMs) !== null && _a !== void 0 ? _a : 5000;
|
|
28486
|
+
}
|
|
28487
|
+
/**
|
|
28488
|
+
* Returns the overall upload timeout in milliseconds for vector store uploads.
|
|
28489
|
+
*/
|
|
28490
|
+
getKnowledgeSourceUploadTimeoutMs() {
|
|
28491
|
+
var _a;
|
|
28492
|
+
return (_a = this.vectorStoreOptions.knowledgeSourceUploadTimeoutMs) !== null && _a !== void 0 ? _a : DEFAULT_KNOWLEDGE_SOURCE_UPLOAD_TIMEOUT_MS;
|
|
28493
|
+
}
|
|
28494
|
+
/**
|
|
28495
|
+
* Returns true if we should continue even if vector store ingestion stalls.
|
|
28496
|
+
*/
|
|
28497
|
+
shouldContinueOnVectorStoreStall() {
|
|
28498
|
+
var _a;
|
|
28499
|
+
return (_a = this.vectorStoreOptions.shouldContinueOnVectorStoreStall) !== null && _a !== void 0 ? _a : true;
|
|
28500
|
+
}
|
|
28501
|
+
/**
|
|
28502
|
+
* Returns vector-store-specific options with extended settings.
|
|
28503
|
+
*/
|
|
28504
|
+
get vectorStoreOptions() {
|
|
28505
|
+
return this.options;
|
|
28506
|
+
}
|
|
28507
|
+
/**
|
|
28508
|
+
* Returns the OpenAI vector stores API surface, supporting stable and beta SDKs.
|
|
28509
|
+
*/
|
|
28510
|
+
getVectorStoresApi(client) {
|
|
28511
|
+
var _a, _b;
|
|
28512
|
+
const vectorStores = (_a = client.vectorStores) !== null && _a !== void 0 ? _a : (_b = client.beta) === null || _b === void 0 ? void 0 : _b.vectorStores;
|
|
28513
|
+
if (!vectorStores) {
|
|
28514
|
+
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.');
|
|
28515
|
+
}
|
|
28516
|
+
return vectorStores;
|
|
28517
|
+
}
|
|
28518
|
+
/**
|
|
28519
|
+
* Downloads a knowledge source URL into a File for vector store upload.
|
|
28520
|
+
*/
|
|
28521
|
+
async downloadKnowledgeSourceFile(options) {
|
|
28522
|
+
var _a;
|
|
28523
|
+
const { source, timeoutMs, logLabel } = options;
|
|
28524
|
+
const startedAtMs = Date.now();
|
|
28525
|
+
const controller = new AbortController();
|
|
28526
|
+
const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
|
|
28527
|
+
if (this.options.isVerbose) {
|
|
28528
|
+
console.info('[🤰]', 'Downloading knowledge source', {
|
|
28529
|
+
source,
|
|
28530
|
+
timeoutMs,
|
|
28531
|
+
logLabel,
|
|
28532
|
+
});
|
|
28533
|
+
}
|
|
28534
|
+
try {
|
|
28535
|
+
const response = await fetch(source, { signal: controller.signal });
|
|
28536
|
+
const contentType = (_a = response.headers.get('content-type')) !== null && _a !== void 0 ? _a : undefined;
|
|
28537
|
+
if (!response.ok) {
|
|
28538
|
+
console.error('[🤰]', 'Failed to download knowledge source', {
|
|
28539
|
+
source,
|
|
28540
|
+
status: response.status,
|
|
28541
|
+
statusText: response.statusText,
|
|
28542
|
+
contentType,
|
|
28543
|
+
elapsedMs: Date.now() - startedAtMs,
|
|
28544
|
+
logLabel,
|
|
28545
|
+
});
|
|
28546
|
+
return null;
|
|
28547
|
+
}
|
|
28548
|
+
const buffer = await response.arrayBuffer();
|
|
28549
|
+
let filename = source.split('/').pop() || 'downloaded-file';
|
|
28550
|
+
try {
|
|
28551
|
+
const url = new URL(source);
|
|
28552
|
+
filename = url.pathname.split('/').pop() || filename;
|
|
28553
|
+
}
|
|
28554
|
+
catch (error) {
|
|
28555
|
+
// Keep default filename
|
|
28556
|
+
}
|
|
28557
|
+
const file = new File([buffer], filename, contentType ? { type: contentType } : undefined);
|
|
28558
|
+
const elapsedMs = Date.now() - startedAtMs;
|
|
28559
|
+
const sizeBytes = buffer.byteLength;
|
|
28560
|
+
if (this.options.isVerbose) {
|
|
28561
|
+
console.info('[🤰]', 'Downloaded knowledge source', {
|
|
28562
|
+
source,
|
|
28563
|
+
filename,
|
|
28564
|
+
sizeBytes,
|
|
28565
|
+
contentType,
|
|
28566
|
+
elapsedMs,
|
|
28567
|
+
logLabel,
|
|
28568
|
+
});
|
|
28569
|
+
}
|
|
28570
|
+
return { file, sizeBytes, filename, elapsedMs };
|
|
28571
|
+
}
|
|
28572
|
+
catch (error) {
|
|
28573
|
+
assertsError(error);
|
|
28574
|
+
console.error('[🤰]', 'Error downloading knowledge source', {
|
|
28575
|
+
source,
|
|
28576
|
+
elapsedMs: Date.now() - startedAtMs,
|
|
28577
|
+
logLabel,
|
|
28578
|
+
error: serializeError(error),
|
|
28579
|
+
});
|
|
28580
|
+
return null;
|
|
28581
|
+
}
|
|
28582
|
+
finally {
|
|
28583
|
+
clearTimeout(timeoutId);
|
|
28584
|
+
}
|
|
28585
|
+
}
|
|
28586
|
+
/**
|
|
28587
|
+
* Logs vector store file batch diagnostics to help trace ingestion stalls or failures.
|
|
28588
|
+
*/
|
|
28589
|
+
async logVectorStoreFileBatchDiagnostics(options) {
|
|
28590
|
+
var _a, _b, _c, _d, _e;
|
|
28591
|
+
const { client, vectorStoreId, batchId, uploadedFiles, logLabel, reason } = options;
|
|
28592
|
+
if (reason === 'stalled' && !this.options.isVerbose) {
|
|
28593
|
+
return;
|
|
28594
|
+
}
|
|
28595
|
+
if (!batchId.startsWith('vsfb_')) {
|
|
28596
|
+
console.error('[🤰]', 'Vector store file batch diagnostics skipped (invalid batch id)', {
|
|
28597
|
+
vectorStoreId,
|
|
28598
|
+
batchId,
|
|
28599
|
+
reason,
|
|
28600
|
+
logLabel,
|
|
28601
|
+
});
|
|
28602
|
+
return;
|
|
28603
|
+
}
|
|
28604
|
+
const fileIdToMetadata = new Map();
|
|
28605
|
+
for (const file of uploadedFiles) {
|
|
28606
|
+
fileIdToMetadata.set(file.fileId, file);
|
|
28607
|
+
}
|
|
28608
|
+
try {
|
|
28609
|
+
const vectorStores = this.getVectorStoresApi(client);
|
|
28610
|
+
const limit = Math.min(100, Math.max(10, uploadedFiles.length));
|
|
28611
|
+
const batchFilesPage = await vectorStores.fileBatches.listFiles(batchId, {
|
|
28612
|
+
vector_store_id: vectorStoreId,
|
|
28613
|
+
limit,
|
|
28614
|
+
});
|
|
28615
|
+
const batchFiles = (_a = batchFilesPage.data) !== null && _a !== void 0 ? _a : [];
|
|
28616
|
+
const statusCounts = {
|
|
28617
|
+
in_progress: 0,
|
|
28618
|
+
completed: 0,
|
|
28619
|
+
failed: 0,
|
|
28620
|
+
cancelled: 0,
|
|
28621
|
+
};
|
|
28622
|
+
const errorSamples = [];
|
|
28623
|
+
const inProgressSamples = [];
|
|
28624
|
+
const batchFileIds = new Set();
|
|
28625
|
+
for (const file of batchFiles) {
|
|
28626
|
+
const status = (_b = file.status) !== null && _b !== void 0 ? _b : 'unknown';
|
|
28627
|
+
statusCounts[status] = ((_c = statusCounts[status]) !== null && _c !== void 0 ? _c : 0) + 1;
|
|
28628
|
+
const vectorStoreFileId = file.id;
|
|
28629
|
+
const uploadedFileId = (_d = file.file_id) !== null && _d !== void 0 ? _d : file.fileId;
|
|
28630
|
+
const fileId = uploadedFileId !== null && uploadedFileId !== void 0 ? uploadedFileId : vectorStoreFileId;
|
|
28631
|
+
batchFileIds.add(fileId);
|
|
28632
|
+
const metadata = fileIdToMetadata.get(fileId);
|
|
28633
|
+
if (status === 'failed') {
|
|
28634
|
+
errorSamples.push({
|
|
28635
|
+
fileId,
|
|
28636
|
+
status,
|
|
28637
|
+
error: (_e = file.last_error) === null || _e === void 0 ? void 0 : _e.message,
|
|
28638
|
+
filename: metadata === null || metadata === void 0 ? void 0 : metadata.filename,
|
|
28639
|
+
vectorStoreFileId: uploadedFileId ? vectorStoreFileId : undefined,
|
|
28640
|
+
});
|
|
28641
|
+
}
|
|
28642
|
+
if (status === 'in_progress') {
|
|
28643
|
+
inProgressSamples.push({
|
|
28644
|
+
fileId,
|
|
28645
|
+
filename: metadata === null || metadata === void 0 ? void 0 : metadata.filename,
|
|
28646
|
+
vectorStoreFileId: uploadedFileId ? vectorStoreFileId : undefined,
|
|
28647
|
+
});
|
|
28648
|
+
}
|
|
28649
|
+
}
|
|
28650
|
+
const missingSamples = uploadedFiles
|
|
28651
|
+
.filter((file) => !batchFileIds.has(file.fileId))
|
|
28652
|
+
.slice(0, 5)
|
|
28653
|
+
.map((file) => ({
|
|
28654
|
+
fileId: file.fileId,
|
|
28655
|
+
filename: file.filename,
|
|
28656
|
+
sizeBytes: file.sizeBytes,
|
|
28657
|
+
}));
|
|
28658
|
+
const vectorStore = await vectorStores.retrieve(vectorStoreId);
|
|
28659
|
+
const logPayload = {
|
|
28660
|
+
vectorStoreId,
|
|
28661
|
+
batchId,
|
|
28662
|
+
reason,
|
|
28663
|
+
vectorStoreStatus: vectorStore.status,
|
|
28664
|
+
vectorStoreFileCounts: vectorStore.file_counts,
|
|
28665
|
+
vectorStoreUsageBytes: vectorStore.usage_bytes,
|
|
28666
|
+
batchFileCount: batchFiles.length,
|
|
28667
|
+
statusCounts,
|
|
28668
|
+
errorSamples: errorSamples.slice(0, 5),
|
|
28669
|
+
inProgressSamples,
|
|
28670
|
+
missingFileCount: uploadedFiles.length - batchFileIds.size,
|
|
28671
|
+
missingSamples,
|
|
28672
|
+
logLabel,
|
|
28673
|
+
};
|
|
28674
|
+
const logFunction = reason === 'stalled' ? console.info : console.error;
|
|
28675
|
+
logFunction('[🤰]', 'Vector store file batch diagnostics', logPayload);
|
|
28676
|
+
}
|
|
28677
|
+
catch (error) {
|
|
28678
|
+
assertsError(error);
|
|
28679
|
+
console.error('[🤰]', 'Vector store file batch diagnostics failed', {
|
|
28680
|
+
vectorStoreId,
|
|
28681
|
+
batchId,
|
|
28682
|
+
reason,
|
|
28683
|
+
logLabel,
|
|
28684
|
+
error: serializeError(error),
|
|
28685
|
+
});
|
|
28686
|
+
}
|
|
28687
|
+
}
|
|
28688
|
+
/**
|
|
28689
|
+
* Uploads knowledge source files to the vector store and polls until processing completes.
|
|
28690
|
+
*/
|
|
28691
|
+
async uploadKnowledgeSourceFilesToVectorStore(options) {
|
|
28692
|
+
var _a, _b, _c, _d, _e, _f;
|
|
28693
|
+
const { client, vectorStoreId, files, totalBytes, logLabel } = options;
|
|
28694
|
+
const vectorStores = this.getVectorStoresApi(client);
|
|
28695
|
+
const uploadStartedAtMs = Date.now();
|
|
28696
|
+
const maxConcurrency = Math.max(1, this.getKnowledgeSourceUploadMaxConcurrency());
|
|
28697
|
+
const pollIntervalMs = Math.max(1000, this.getKnowledgeSourceUploadPollIntervalMs());
|
|
28698
|
+
const uploadTimeoutMs = Math.max(1000, this.getKnowledgeSourceUploadTimeoutMs());
|
|
28699
|
+
if (this.options.isVerbose) {
|
|
28700
|
+
console.info('[🤰]', 'Uploading knowledge source files to OpenAI', {
|
|
28701
|
+
vectorStoreId,
|
|
28702
|
+
fileCount: files.length,
|
|
28703
|
+
totalBytes,
|
|
28704
|
+
maxConcurrency,
|
|
28705
|
+
pollIntervalMs,
|
|
28706
|
+
uploadTimeoutMs,
|
|
28707
|
+
logLabel,
|
|
28708
|
+
});
|
|
28709
|
+
}
|
|
28710
|
+
const fileTypeSummary = {};
|
|
28711
|
+
for (const file of files) {
|
|
28712
|
+
const filename = (_a = file.name) !== null && _a !== void 0 ? _a : '';
|
|
28713
|
+
const extension = filename.includes('.')
|
|
28714
|
+
? (_c = (_b = filename.split('.').pop()) === null || _b === void 0 ? void 0 : _b.toLowerCase()) !== null && _c !== void 0 ? _c : 'unknown'
|
|
28715
|
+
: 'unknown';
|
|
28716
|
+
const sizeBytes = typeof file.size === 'number' ? file.size : 0;
|
|
28717
|
+
const summary = (_d = fileTypeSummary[extension]) !== null && _d !== void 0 ? _d : { count: 0, totalBytes: 0 };
|
|
28718
|
+
summary.count += 1;
|
|
28719
|
+
summary.totalBytes += sizeBytes;
|
|
28720
|
+
fileTypeSummary[extension] = summary;
|
|
28721
|
+
}
|
|
28722
|
+
if (this.options.isVerbose) {
|
|
28723
|
+
console.info('[🤰]', 'Knowledge source file summary', {
|
|
28724
|
+
vectorStoreId,
|
|
28725
|
+
fileCount: files.length,
|
|
28726
|
+
totalBytes,
|
|
28727
|
+
fileTypeSummary,
|
|
28728
|
+
logLabel,
|
|
28729
|
+
});
|
|
28730
|
+
}
|
|
28731
|
+
const fileEntries = files.map((file, index) => ({ file, index }));
|
|
28732
|
+
const fileIterator = fileEntries.values();
|
|
28733
|
+
const fileIds = [];
|
|
28734
|
+
const uploadedFiles = [];
|
|
28735
|
+
const failedUploads = [];
|
|
28736
|
+
let uploadedCount = 0;
|
|
28737
|
+
const processFiles = async (iterator) => {
|
|
28738
|
+
var _a, _b;
|
|
28739
|
+
for (const { file, index } of iterator) {
|
|
28740
|
+
const uploadIndex = index + 1;
|
|
28741
|
+
const filename = file.name || `knowledge-source-${uploadIndex}`;
|
|
28742
|
+
const extension = filename.includes('.')
|
|
28743
|
+
? (_b = (_a = filename.split('.').pop()) === null || _a === void 0 ? void 0 : _a.toLowerCase()) !== null && _b !== void 0 ? _b : 'unknown'
|
|
28744
|
+
: 'unknown';
|
|
28745
|
+
const sizeBytes = typeof file.size === 'number' ? file.size : undefined;
|
|
28746
|
+
const fileUploadStartedAtMs = Date.now();
|
|
28747
|
+
if (this.options.isVerbose) {
|
|
28748
|
+
console.info('[🤰]', 'Uploading knowledge source file', {
|
|
28749
|
+
index: uploadIndex,
|
|
28750
|
+
total: files.length,
|
|
28751
|
+
filename,
|
|
28752
|
+
extension,
|
|
28753
|
+
sizeBytes,
|
|
28754
|
+
logLabel,
|
|
28755
|
+
});
|
|
28756
|
+
}
|
|
28757
|
+
try {
|
|
28758
|
+
const uploaded = await client.files.create({ file, purpose: 'assistants' });
|
|
28759
|
+
fileIds.push(uploaded.id);
|
|
28760
|
+
uploadedFiles.push({ fileId: uploaded.id, filename, sizeBytes });
|
|
28761
|
+
uploadedCount += 1;
|
|
28762
|
+
if (this.options.isVerbose) {
|
|
28763
|
+
console.info('[🤰]', 'Uploaded knowledge source file', {
|
|
28764
|
+
index: uploadIndex,
|
|
28765
|
+
total: files.length,
|
|
28766
|
+
filename,
|
|
28767
|
+
sizeBytes,
|
|
28768
|
+
fileId: uploaded.id,
|
|
28769
|
+
elapsedMs: Date.now() - fileUploadStartedAtMs,
|
|
28770
|
+
logLabel,
|
|
28771
|
+
});
|
|
28772
|
+
}
|
|
28773
|
+
}
|
|
28774
|
+
catch (error) {
|
|
28775
|
+
assertsError(error);
|
|
28776
|
+
const serializedError = serializeError(error);
|
|
28777
|
+
failedUploads.push({ index: uploadIndex, filename, error: serializedError });
|
|
28778
|
+
console.error('[🤰]', 'Failed to upload knowledge source file', {
|
|
28779
|
+
index: uploadIndex,
|
|
28780
|
+
total: files.length,
|
|
28781
|
+
filename,
|
|
28782
|
+
sizeBytes,
|
|
28783
|
+
elapsedMs: Date.now() - fileUploadStartedAtMs,
|
|
28784
|
+
logLabel,
|
|
28785
|
+
error: serializedError,
|
|
28786
|
+
});
|
|
28787
|
+
}
|
|
28788
|
+
}
|
|
28789
|
+
};
|
|
28790
|
+
const workerCount = Math.min(maxConcurrency, files.length);
|
|
28791
|
+
const workers = Array.from({ length: workerCount }, () => processFiles(fileIterator));
|
|
28792
|
+
await Promise.all(workers);
|
|
28793
|
+
if (this.options.isVerbose) {
|
|
28794
|
+
console.info('[🤰]', 'Finished uploading knowledge source files', {
|
|
28795
|
+
vectorStoreId,
|
|
28796
|
+
fileCount: files.length,
|
|
28797
|
+
uploadedCount,
|
|
28798
|
+
failedCount: failedUploads.length,
|
|
28799
|
+
elapsedMs: Date.now() - uploadStartedAtMs,
|
|
28800
|
+
failedSamples: failedUploads.slice(0, 3),
|
|
28801
|
+
logLabel,
|
|
28802
|
+
});
|
|
28803
|
+
}
|
|
28804
|
+
if (fileIds.length === 0) {
|
|
28805
|
+
console.error('[🤰]', 'No knowledge source files were uploaded', {
|
|
28806
|
+
vectorStoreId,
|
|
28807
|
+
fileCount: files.length,
|
|
28808
|
+
failedCount: failedUploads.length,
|
|
28809
|
+
logLabel,
|
|
28810
|
+
});
|
|
28811
|
+
return null;
|
|
28812
|
+
}
|
|
28813
|
+
const batch = await vectorStores.fileBatches.create(vectorStoreId, {
|
|
28814
|
+
file_ids: fileIds,
|
|
28815
|
+
});
|
|
28816
|
+
const expectedBatchId = batch.id;
|
|
28817
|
+
const expectedBatchIdValid = expectedBatchId.startsWith('vsfb_');
|
|
28818
|
+
if (!expectedBatchIdValid) {
|
|
28819
|
+
console.error('[🤰]', 'Vector store file batch id looks invalid', {
|
|
28820
|
+
vectorStoreId,
|
|
28821
|
+
batchId: expectedBatchId,
|
|
28822
|
+
batchVectorStoreId: batch.vector_store_id,
|
|
28823
|
+
logLabel,
|
|
28824
|
+
});
|
|
28825
|
+
}
|
|
28826
|
+
else if (batch.vector_store_id !== vectorStoreId) {
|
|
28827
|
+
console.error('[🤰]', 'Vector store file batch vector store id mismatch', {
|
|
28828
|
+
vectorStoreId,
|
|
28829
|
+
batchId: expectedBatchId,
|
|
28830
|
+
batchVectorStoreId: batch.vector_store_id,
|
|
28831
|
+
logLabel,
|
|
28832
|
+
});
|
|
28833
|
+
}
|
|
28834
|
+
if (this.options.isVerbose) {
|
|
28835
|
+
console.info('[🤰]', 'Created vector store file batch', {
|
|
28836
|
+
vectorStoreId,
|
|
28837
|
+
batchId: expectedBatchId,
|
|
28838
|
+
fileCount: fileIds.length,
|
|
28839
|
+
logLabel,
|
|
28840
|
+
});
|
|
28841
|
+
}
|
|
28842
|
+
const pollStartedAtMs = Date.now();
|
|
28843
|
+
const progressLogIntervalMs = Math.max(VECTOR_STORE_PROGRESS_LOG_INTERVAL_MIN_MS, pollIntervalMs);
|
|
28844
|
+
const diagnosticsIntervalMs = Math.max(60000, pollIntervalMs * 5);
|
|
28845
|
+
// let lastStatus: string | undefined;
|
|
28846
|
+
let lastCountsKey = '';
|
|
28847
|
+
let lastProgressKey = '';
|
|
28848
|
+
let lastLogAtMs = 0;
|
|
28849
|
+
let lastProgressAtMs = pollStartedAtMs;
|
|
28850
|
+
let lastDiagnosticsAtMs = pollStartedAtMs;
|
|
28851
|
+
let latestBatch = batch;
|
|
28852
|
+
let loggedBatchIdMismatch = false;
|
|
28853
|
+
let loggedBatchIdFallback = false;
|
|
28854
|
+
let loggedBatchIdInvalid = false;
|
|
28855
|
+
let shouldPoll = true;
|
|
28856
|
+
while (shouldPoll) {
|
|
28857
|
+
const nowMs = Date.now();
|
|
28858
|
+
// [🤰] Note: Sometimes OpenAI returns Vector Store object instead of Batch object, or IDs get swapped.
|
|
28859
|
+
const rawBatchId = typeof latestBatch.id === 'string' ? latestBatch.id : '';
|
|
28860
|
+
const rawVectorStoreId = latestBatch.vector_store_id;
|
|
28861
|
+
let returnedBatchId = rawBatchId;
|
|
28862
|
+
let returnedBatchIdValid = typeof returnedBatchId === 'string' && returnedBatchId.startsWith('vsfb_');
|
|
28863
|
+
if (!returnedBatchIdValid && expectedBatchIdValid) {
|
|
28864
|
+
if (!loggedBatchIdFallback) {
|
|
28865
|
+
console.error('[🤰]', 'Vector store file batch id missing from response; falling back to expected', {
|
|
28866
|
+
vectorStoreId,
|
|
28867
|
+
expectedBatchId,
|
|
28868
|
+
returnedBatchId,
|
|
28869
|
+
rawVectorStoreId,
|
|
28870
|
+
logLabel,
|
|
28871
|
+
});
|
|
28872
|
+
loggedBatchIdFallback = true;
|
|
28873
|
+
}
|
|
28874
|
+
returnedBatchId = expectedBatchId;
|
|
28875
|
+
returnedBatchIdValid = true;
|
|
28876
|
+
}
|
|
28877
|
+
if (!returnedBatchIdValid && !loggedBatchIdInvalid) {
|
|
28878
|
+
console.error('[🤰]', 'Vector store file batch id is invalid; stopping polling', {
|
|
28879
|
+
vectorStoreId,
|
|
28880
|
+
expectedBatchId,
|
|
28881
|
+
returnedBatchId,
|
|
28882
|
+
rawVectorStoreId,
|
|
28883
|
+
logLabel,
|
|
28884
|
+
});
|
|
28885
|
+
loggedBatchIdInvalid = true;
|
|
28886
|
+
}
|
|
28887
|
+
const batchIdMismatch = expectedBatchIdValid && returnedBatchIdValid && returnedBatchId !== expectedBatchId;
|
|
28888
|
+
if (batchIdMismatch && !loggedBatchIdMismatch) {
|
|
28889
|
+
console.error('[🤰]', 'Vector store file batch id mismatch', {
|
|
28890
|
+
vectorStoreId,
|
|
28891
|
+
expectedBatchId,
|
|
28892
|
+
returnedBatchId,
|
|
28893
|
+
logLabel,
|
|
28894
|
+
});
|
|
28895
|
+
loggedBatchIdMismatch = true;
|
|
28896
|
+
}
|
|
28897
|
+
if (returnedBatchIdValid) {
|
|
28898
|
+
latestBatch = await vectorStores.fileBatches.retrieve(returnedBatchId, {
|
|
28899
|
+
vector_store_id: vectorStoreId,
|
|
28900
|
+
});
|
|
28901
|
+
}
|
|
28902
|
+
else {
|
|
28903
|
+
shouldPoll = false;
|
|
28904
|
+
continue;
|
|
28905
|
+
}
|
|
28906
|
+
const status = (_e = latestBatch.status) !== null && _e !== void 0 ? _e : 'unknown';
|
|
28907
|
+
const fileCounts = (_f = latestBatch.file_counts) !== null && _f !== void 0 ? _f : {};
|
|
28908
|
+
const progressKey = JSON.stringify(fileCounts);
|
|
28909
|
+
const statusCountsKey = `${status}-${progressKey}`;
|
|
28910
|
+
const isProgressing = progressKey !== lastProgressKey;
|
|
28911
|
+
if (isProgressing) {
|
|
28912
|
+
lastProgressAtMs = nowMs;
|
|
28913
|
+
lastProgressKey = progressKey;
|
|
28914
|
+
}
|
|
28915
|
+
if (this.options.isVerbose &&
|
|
28916
|
+
(statusCountsKey !== lastCountsKey || nowMs - lastLogAtMs >= progressLogIntervalMs)) {
|
|
28917
|
+
console.info('[🤰]', 'Vector store file batch status', {
|
|
28918
|
+
vectorStoreId,
|
|
28919
|
+
batchId: returnedBatchId,
|
|
28920
|
+
status,
|
|
28921
|
+
fileCounts,
|
|
28922
|
+
elapsedMs: nowMs - pollStartedAtMs,
|
|
28923
|
+
logLabel,
|
|
28924
|
+
});
|
|
28925
|
+
lastCountsKey = statusCountsKey;
|
|
28926
|
+
lastLogAtMs = nowMs;
|
|
28927
|
+
}
|
|
28928
|
+
if (status === 'in_progress' &&
|
|
28929
|
+
nowMs - lastProgressAtMs >= VECTOR_STORE_STALL_LOG_THRESHOLD_MS &&
|
|
28930
|
+
nowMs - lastDiagnosticsAtMs >= diagnosticsIntervalMs) {
|
|
28931
|
+
lastDiagnosticsAtMs = nowMs;
|
|
28932
|
+
await this.logVectorStoreFileBatchDiagnostics({
|
|
28933
|
+
client,
|
|
28934
|
+
vectorStoreId,
|
|
28935
|
+
batchId: returnedBatchId,
|
|
28936
|
+
uploadedFiles,
|
|
28937
|
+
logLabel,
|
|
28938
|
+
reason: 'stalled',
|
|
28939
|
+
});
|
|
28940
|
+
}
|
|
28941
|
+
if (status === 'completed') {
|
|
28942
|
+
if (this.options.isVerbose) {
|
|
28943
|
+
console.info('[🤰]', 'Vector store file batch completed', {
|
|
28944
|
+
vectorStoreId,
|
|
28945
|
+
batchId: returnedBatchId,
|
|
28946
|
+
fileCounts,
|
|
28947
|
+
elapsedMs: nowMs - pollStartedAtMs,
|
|
28948
|
+
logLabel,
|
|
28949
|
+
});
|
|
28950
|
+
}
|
|
28951
|
+
shouldPoll = false;
|
|
28952
|
+
continue;
|
|
28953
|
+
}
|
|
28954
|
+
if (status === 'failed') {
|
|
28955
|
+
console.error('[🤰]', 'Vector store file batch completed with failures', {
|
|
28956
|
+
vectorStoreId,
|
|
28957
|
+
batchId: returnedBatchId,
|
|
28958
|
+
fileCounts,
|
|
28959
|
+
elapsedMs: nowMs - pollStartedAtMs,
|
|
28960
|
+
logLabel,
|
|
28961
|
+
});
|
|
28962
|
+
await this.logVectorStoreFileBatchDiagnostics({
|
|
28963
|
+
client,
|
|
28964
|
+
vectorStoreId,
|
|
28965
|
+
batchId: returnedBatchId,
|
|
28966
|
+
uploadedFiles,
|
|
28967
|
+
logLabel,
|
|
28968
|
+
reason: 'failed',
|
|
28969
|
+
});
|
|
28970
|
+
shouldPoll = false;
|
|
28971
|
+
continue;
|
|
28972
|
+
}
|
|
28973
|
+
if (status === 'cancelled') {
|
|
28974
|
+
console.error('[🤰]', 'Vector store file batch did not complete', {
|
|
28975
|
+
vectorStoreId,
|
|
28976
|
+
batchId: returnedBatchId,
|
|
28977
|
+
status,
|
|
28978
|
+
fileCounts,
|
|
28979
|
+
elapsedMs: nowMs - pollStartedAtMs,
|
|
28980
|
+
logLabel,
|
|
28981
|
+
});
|
|
28982
|
+
await this.logVectorStoreFileBatchDiagnostics({
|
|
28983
|
+
client,
|
|
28984
|
+
vectorStoreId,
|
|
28985
|
+
batchId: returnedBatchId,
|
|
28986
|
+
uploadedFiles,
|
|
28987
|
+
logLabel,
|
|
28988
|
+
reason: 'failed',
|
|
28989
|
+
});
|
|
28990
|
+
shouldPoll = false;
|
|
28991
|
+
continue;
|
|
28992
|
+
}
|
|
28993
|
+
if (nowMs - pollStartedAtMs >= uploadTimeoutMs) {
|
|
28994
|
+
console.error('[🤰]', 'Timed out waiting for vector store file batch', {
|
|
28995
|
+
vectorStoreId,
|
|
28996
|
+
batchId: returnedBatchId,
|
|
28997
|
+
fileCounts,
|
|
28998
|
+
elapsedMs: nowMs - pollStartedAtMs,
|
|
28999
|
+
uploadTimeoutMs,
|
|
29000
|
+
logLabel,
|
|
29001
|
+
});
|
|
29002
|
+
await this.logVectorStoreFileBatchDiagnostics({
|
|
29003
|
+
client,
|
|
29004
|
+
vectorStoreId,
|
|
29005
|
+
batchId: returnedBatchId,
|
|
29006
|
+
uploadedFiles,
|
|
29007
|
+
logLabel,
|
|
29008
|
+
reason: 'timeout',
|
|
29009
|
+
});
|
|
29010
|
+
if (this.shouldContinueOnVectorStoreStall()) {
|
|
29011
|
+
console.warn('[🤰]', 'Continuing despite vector store timeout as requested', {
|
|
29012
|
+
vectorStoreId,
|
|
29013
|
+
logLabel,
|
|
29014
|
+
});
|
|
29015
|
+
shouldPoll = false;
|
|
29016
|
+
continue;
|
|
29017
|
+
}
|
|
29018
|
+
try {
|
|
29019
|
+
const cancelBatchId = batchIdMismatch && returnedBatchId.startsWith('vsfb_') ? returnedBatchId : expectedBatchId;
|
|
29020
|
+
if (!cancelBatchId.startsWith('vsfb_')) {
|
|
29021
|
+
console.error('[🤰]', 'Skipping vector store file batch cancel (invalid batch id)', {
|
|
29022
|
+
vectorStoreId,
|
|
29023
|
+
batchId: cancelBatchId,
|
|
29024
|
+
logLabel,
|
|
29025
|
+
});
|
|
29026
|
+
}
|
|
29027
|
+
else {
|
|
29028
|
+
await vectorStores.fileBatches.cancel(cancelBatchId, {
|
|
29029
|
+
vector_store_id: vectorStoreId,
|
|
29030
|
+
});
|
|
29031
|
+
}
|
|
29032
|
+
if (this.options.isVerbose) {
|
|
29033
|
+
console.info('[🤰]', 'Cancelled vector store file batch after timeout', {
|
|
29034
|
+
vectorStoreId,
|
|
29035
|
+
batchId: batchIdMismatch && returnedBatchId.startsWith('vsfb_')
|
|
29036
|
+
? returnedBatchId
|
|
29037
|
+
: expectedBatchId,
|
|
29038
|
+
...(batchIdMismatch ? { returnedBatchId } : {}),
|
|
29039
|
+
logLabel,
|
|
29040
|
+
});
|
|
29041
|
+
}
|
|
29042
|
+
}
|
|
29043
|
+
catch (error) {
|
|
29044
|
+
assertsError(error);
|
|
29045
|
+
console.error('[🤰]', 'Failed to cancel vector store file batch after timeout', {
|
|
29046
|
+
vectorStoreId,
|
|
29047
|
+
batchId: expectedBatchId,
|
|
29048
|
+
...(batchIdMismatch ? { returnedBatchId } : {}),
|
|
29049
|
+
logLabel,
|
|
29050
|
+
error: serializeError(error),
|
|
29051
|
+
});
|
|
29052
|
+
}
|
|
29053
|
+
shouldPoll = false;
|
|
29054
|
+
continue;
|
|
29055
|
+
}
|
|
29056
|
+
await new Promise((resolve) => setTimeout(resolve, pollIntervalMs));
|
|
29057
|
+
}
|
|
29058
|
+
return latestBatch;
|
|
29059
|
+
}
|
|
29060
|
+
/**
|
|
29061
|
+
* Creates a vector store and uploads knowledge sources, returning its ID.
|
|
29062
|
+
*/
|
|
29063
|
+
async createVectorStoreWithKnowledgeSources(options) {
|
|
29064
|
+
const { client, name, knowledgeSources, logLabel } = options;
|
|
29065
|
+
const vectorStores = this.getVectorStoresApi(client);
|
|
29066
|
+
const knowledgeSourcesCount = knowledgeSources.length;
|
|
29067
|
+
const downloadTimeoutMs = this.getKnowledgeSourceDownloadTimeoutMs();
|
|
29068
|
+
if (this.options.isVerbose) {
|
|
29069
|
+
console.info('[🤰]', 'Creating vector store with knowledge sources', {
|
|
29070
|
+
name,
|
|
29071
|
+
knowledgeSourcesCount,
|
|
29072
|
+
downloadTimeoutMs,
|
|
29073
|
+
logLabel,
|
|
29074
|
+
});
|
|
29075
|
+
}
|
|
29076
|
+
const vectorStore = await vectorStores.create({
|
|
29077
|
+
name: `${name} Knowledge Base`,
|
|
29078
|
+
});
|
|
29079
|
+
const vectorStoreId = vectorStore.id;
|
|
29080
|
+
if (this.options.isVerbose) {
|
|
29081
|
+
console.info('[🤰]', 'Vector store created', {
|
|
29082
|
+
vectorStoreId,
|
|
29083
|
+
logLabel,
|
|
29084
|
+
});
|
|
29085
|
+
}
|
|
29086
|
+
const fileStreams = [];
|
|
29087
|
+
const skippedSources = [];
|
|
29088
|
+
let totalBytes = 0;
|
|
29089
|
+
const processingStartedAtMs = Date.now();
|
|
29090
|
+
for (const [index, source] of knowledgeSources.entries()) {
|
|
29091
|
+
try {
|
|
29092
|
+
const sourceType = source.startsWith('http') || source.startsWith('https') ? 'url' : 'file';
|
|
29093
|
+
if (this.options.isVerbose) {
|
|
29094
|
+
console.info('[🤰]', 'Processing knowledge source', {
|
|
29095
|
+
index: index + 1,
|
|
29096
|
+
total: knowledgeSourcesCount,
|
|
29097
|
+
source,
|
|
29098
|
+
sourceType,
|
|
29099
|
+
logLabel,
|
|
29100
|
+
});
|
|
29101
|
+
}
|
|
29102
|
+
// Check if it's a URL
|
|
29103
|
+
if (source.startsWith('http://') || source.startsWith('https://')) {
|
|
29104
|
+
const downloadResult = await this.downloadKnowledgeSourceFile({
|
|
29105
|
+
source,
|
|
29106
|
+
timeoutMs: downloadTimeoutMs,
|
|
29107
|
+
logLabel,
|
|
29108
|
+
});
|
|
29109
|
+
if (downloadResult) {
|
|
29110
|
+
fileStreams.push(downloadResult.file);
|
|
29111
|
+
totalBytes += downloadResult.sizeBytes;
|
|
29112
|
+
}
|
|
29113
|
+
else {
|
|
29114
|
+
skippedSources.push({ source, reason: 'download_failed' });
|
|
29115
|
+
}
|
|
29116
|
+
}
|
|
29117
|
+
else {
|
|
29118
|
+
skippedSources.push({ source, reason: 'unsupported_source_type' });
|
|
29119
|
+
if (this.options.isVerbose) {
|
|
29120
|
+
console.info('[🤰]', 'Skipping knowledge source (unsupported type)', {
|
|
29121
|
+
source,
|
|
29122
|
+
sourceType,
|
|
29123
|
+
logLabel,
|
|
29124
|
+
});
|
|
29125
|
+
}
|
|
29126
|
+
/*
|
|
29127
|
+
TODO: [🤰] Resolve problem with browser environment
|
|
29128
|
+
// Assume it's a local file path
|
|
29129
|
+
// Note: This will work in Node.js environment
|
|
29130
|
+
// For browser environments, this would need different handling
|
|
29131
|
+
const fs = await import('fs');
|
|
29132
|
+
const fileStream = fs.createReadStream(source);
|
|
29133
|
+
fileStreams.push(fileStream);
|
|
29134
|
+
*/
|
|
29135
|
+
}
|
|
29136
|
+
}
|
|
29137
|
+
catch (error) {
|
|
29138
|
+
assertsError(error);
|
|
29139
|
+
skippedSources.push({ source, reason: 'processing_error' });
|
|
29140
|
+
console.error('[🤰]', 'Error processing knowledge source', {
|
|
29141
|
+
source,
|
|
29142
|
+
logLabel,
|
|
29143
|
+
error: serializeError(error),
|
|
29144
|
+
});
|
|
29145
|
+
}
|
|
29146
|
+
}
|
|
29147
|
+
if (this.options.isVerbose) {
|
|
29148
|
+
console.info('[🤰]', 'Finished processing knowledge sources', {
|
|
29149
|
+
total: knowledgeSourcesCount,
|
|
29150
|
+
downloadedCount: fileStreams.length,
|
|
29151
|
+
skippedCount: skippedSources.length,
|
|
29152
|
+
totalBytes,
|
|
29153
|
+
elapsedMs: Date.now() - processingStartedAtMs,
|
|
29154
|
+
skippedSamples: skippedSources.slice(0, 3),
|
|
29155
|
+
logLabel,
|
|
29156
|
+
});
|
|
29157
|
+
}
|
|
29158
|
+
if (fileStreams.length > 0) {
|
|
29159
|
+
if (this.options.isVerbose) {
|
|
29160
|
+
console.info('[🤰]', 'Uploading files to vector store', {
|
|
29161
|
+
vectorStoreId,
|
|
29162
|
+
fileCount: fileStreams.length,
|
|
29163
|
+
totalBytes,
|
|
29164
|
+
maxConcurrency: this.getKnowledgeSourceUploadMaxConcurrency(),
|
|
29165
|
+
pollIntervalMs: this.getKnowledgeSourceUploadPollIntervalMs(),
|
|
29166
|
+
uploadTimeoutMs: this.getKnowledgeSourceUploadTimeoutMs(),
|
|
29167
|
+
logLabel,
|
|
29168
|
+
});
|
|
29169
|
+
}
|
|
29170
|
+
try {
|
|
29171
|
+
await this.uploadKnowledgeSourceFilesToVectorStore({
|
|
29172
|
+
client,
|
|
29173
|
+
vectorStoreId,
|
|
29174
|
+
files: fileStreams,
|
|
29175
|
+
totalBytes,
|
|
29176
|
+
logLabel,
|
|
29177
|
+
});
|
|
29178
|
+
}
|
|
29179
|
+
catch (error) {
|
|
29180
|
+
assertsError(error);
|
|
29181
|
+
console.error('[🤰]', 'Error uploading files to vector store', {
|
|
29182
|
+
vectorStoreId,
|
|
29183
|
+
logLabel,
|
|
29184
|
+
error: serializeError(error),
|
|
29185
|
+
});
|
|
29186
|
+
}
|
|
29187
|
+
}
|
|
29188
|
+
else if (this.options.isVerbose) {
|
|
29189
|
+
console.info('[🤰]', 'No knowledge source files to upload', {
|
|
29190
|
+
vectorStoreId,
|
|
29191
|
+
skippedCount: skippedSources.length,
|
|
29192
|
+
logLabel,
|
|
29193
|
+
});
|
|
29194
|
+
}
|
|
29195
|
+
return {
|
|
29196
|
+
vectorStoreId,
|
|
29197
|
+
uploadedFileCount: fileStreams.length,
|
|
29198
|
+
skippedCount: skippedSources.length,
|
|
29199
|
+
totalBytes,
|
|
29200
|
+
};
|
|
29201
|
+
}
|
|
29202
|
+
}
|
|
29203
|
+
|
|
28472
29204
|
/**
|
|
28473
29205
|
* Uploads files to OpenAI and returns their IDs
|
|
28474
29206
|
*
|
|
@@ -28502,10 +29234,10 @@ async function uploadFilesToOpenAi(client, files) {
|
|
|
28502
29234
|
* - `OpenAiAssistantExecutionTools` - which is a specific implementation of `LlmExecutionTools` for OpenAI models with assistant capabilities, recommended for usage in `Agent` or `AgentLlmExecutionTools`
|
|
28503
29235
|
* - `RemoteAgent` - which is an `Agent` that connects to a Promptbook Agents Server
|
|
28504
29236
|
*
|
|
29237
|
+
* @deprecated Use `OpenAiAgentKitExecutionTools` instead.
|
|
28505
29238
|
* @public exported from `@promptbook/openai`
|
|
28506
|
-
* @deprecated Use `OpenAiAgentExecutionTools` instead which uses the new OpenAI Responses API
|
|
28507
29239
|
*/
|
|
28508
|
-
class OpenAiAssistantExecutionTools extends
|
|
29240
|
+
class OpenAiAssistantExecutionTools extends OpenAiVectorStoreHandler {
|
|
28509
29241
|
/**
|
|
28510
29242
|
* Creates OpenAI Execution Tools.
|
|
28511
29243
|
*
|
|
@@ -28634,8 +29366,7 @@ class OpenAiAssistantExecutionTools extends OpenAiExecutionTools {
|
|
|
28634
29366
|
console.info(colors.bgWhite('rawRequest (non-streaming with tools)'), JSON.stringify(rawRequest, null, 4));
|
|
28635
29367
|
}
|
|
28636
29368
|
// Create thread and run
|
|
28637
|
-
|
|
28638
|
-
let run = threadAndRun;
|
|
29369
|
+
let run = (await client.beta.threads.createAndRun(rawRequest));
|
|
28639
29370
|
const completedToolCalls = [];
|
|
28640
29371
|
const toolCallStartedAt = new Map();
|
|
28641
29372
|
// Poll until run completes or requires action
|
|
@@ -28730,14 +29461,14 @@ class OpenAiAssistantExecutionTools extends OpenAiExecutionTools {
|
|
|
28730
29461
|
}
|
|
28731
29462
|
}
|
|
28732
29463
|
// Submit tool outputs
|
|
28733
|
-
run = await client.beta.threads.runs.submitToolOutputs(run.thread_id, run.id, {
|
|
29464
|
+
run = (await client.beta.threads.runs.submitToolOutputs(run.thread_id, run.id, {
|
|
28734
29465
|
tool_outputs: toolOutputs,
|
|
28735
|
-
});
|
|
29466
|
+
}));
|
|
28736
29467
|
}
|
|
28737
29468
|
else {
|
|
28738
29469
|
// Wait a bit before polling again
|
|
28739
29470
|
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
28740
|
-
run = await client.beta.threads.runs.retrieve(run.thread_id, run.id);
|
|
29471
|
+
run = (await client.beta.threads.runs.retrieve(run.thread_id, run.id));
|
|
28741
29472
|
}
|
|
28742
29473
|
}
|
|
28743
29474
|
if (run.status !== 'completed') {
|
|
@@ -28962,88 +29693,13 @@ class OpenAiAssistantExecutionTools extends OpenAiExecutionTools {
|
|
|
28962
29693
|
let vectorStoreId;
|
|
28963
29694
|
// If knowledge sources are provided, create a vector store with them
|
|
28964
29695
|
if (knowledgeSources && knowledgeSources.length > 0) {
|
|
28965
|
-
|
|
28966
|
-
|
|
28967
|
-
|
|
28968
|
-
|
|
28969
|
-
|
|
28970
|
-
}
|
|
28971
|
-
// Create a vector store
|
|
28972
|
-
const vectorStore = await client.beta.vectorStores.create({
|
|
28973
|
-
name: `${name} Knowledge Base`,
|
|
29696
|
+
const vectorStoreResult = await this.createVectorStoreWithKnowledgeSources({
|
|
29697
|
+
client,
|
|
29698
|
+
name,
|
|
29699
|
+
knowledgeSources,
|
|
29700
|
+
logLabel: 'assistant creation',
|
|
28974
29701
|
});
|
|
28975
|
-
vectorStoreId =
|
|
28976
|
-
if (this.options.isVerbose) {
|
|
28977
|
-
console.info('[🤰]', 'Vector store created', {
|
|
28978
|
-
vectorStoreId,
|
|
28979
|
-
});
|
|
28980
|
-
}
|
|
28981
|
-
// Upload files from knowledge sources to the vector store
|
|
28982
|
-
const fileStreams = [];
|
|
28983
|
-
for (const [index, source] of knowledgeSources.entries()) {
|
|
28984
|
-
try {
|
|
28985
|
-
if (this.options.isVerbose) {
|
|
28986
|
-
console.info('[🤰]', 'Processing knowledge source', {
|
|
28987
|
-
index: index + 1,
|
|
28988
|
-
total: knowledgeSources.length,
|
|
28989
|
-
source,
|
|
28990
|
-
sourceType: source.startsWith('http') || source.startsWith('https') ? 'url' : 'file',
|
|
28991
|
-
});
|
|
28992
|
-
}
|
|
28993
|
-
// Check if it's a URL
|
|
28994
|
-
if (source.startsWith('http://') || source.startsWith('https://')) {
|
|
28995
|
-
// Download the file
|
|
28996
|
-
const response = await fetch(source);
|
|
28997
|
-
if (!response.ok) {
|
|
28998
|
-
console.error(`Failed to download ${source}: ${response.statusText}`);
|
|
28999
|
-
continue;
|
|
29000
|
-
}
|
|
29001
|
-
const buffer = await response.arrayBuffer();
|
|
29002
|
-
let filename = source.split('/').pop() || 'downloaded-file';
|
|
29003
|
-
try {
|
|
29004
|
-
const url = new URL(source);
|
|
29005
|
-
filename = url.pathname.split('/').pop() || filename;
|
|
29006
|
-
}
|
|
29007
|
-
catch (error) {
|
|
29008
|
-
// Keep default filename
|
|
29009
|
-
}
|
|
29010
|
-
const blob = new Blob([buffer]);
|
|
29011
|
-
const file = new File([blob], filename);
|
|
29012
|
-
fileStreams.push(file);
|
|
29013
|
-
}
|
|
29014
|
-
else {
|
|
29015
|
-
/*
|
|
29016
|
-
TODO: [🐱🚀] Resolve problem with browser environment
|
|
29017
|
-
// Assume it's a local file path
|
|
29018
|
-
// Note: This will work in Node.js environment
|
|
29019
|
-
// For browser environments, this would need different handling
|
|
29020
|
-
const fs = await import('fs');
|
|
29021
|
-
const fileStream = fs.createReadStream(source);
|
|
29022
|
-
fileStreams.push(fileStream);
|
|
29023
|
-
*/
|
|
29024
|
-
}
|
|
29025
|
-
}
|
|
29026
|
-
catch (error) {
|
|
29027
|
-
console.error(`Error processing knowledge source ${source}:`, error);
|
|
29028
|
-
}
|
|
29029
|
-
}
|
|
29030
|
-
// Batch upload files to the vector store
|
|
29031
|
-
if (fileStreams.length > 0) {
|
|
29032
|
-
try {
|
|
29033
|
-
await client.beta.vectorStores.fileBatches.uploadAndPoll(vectorStoreId, {
|
|
29034
|
-
files: fileStreams,
|
|
29035
|
-
});
|
|
29036
|
-
if (this.options.isVerbose) {
|
|
29037
|
-
console.info('[🤰]', 'Uploaded files to vector store', {
|
|
29038
|
-
vectorStoreId,
|
|
29039
|
-
fileCount: fileStreams.length,
|
|
29040
|
-
});
|
|
29041
|
-
}
|
|
29042
|
-
}
|
|
29043
|
-
catch (error) {
|
|
29044
|
-
console.error('Error uploading files to vector store:', error);
|
|
29045
|
-
}
|
|
29046
|
-
}
|
|
29702
|
+
vectorStoreId = vectorStoreResult.vectorStoreId;
|
|
29047
29703
|
}
|
|
29048
29704
|
// Create assistant with vector store attached
|
|
29049
29705
|
const assistantConfig = {
|
|
@@ -29110,91 +29766,14 @@ class OpenAiAssistantExecutionTools extends OpenAiExecutionTools {
|
|
|
29110
29766
|
const client = await this.getClient();
|
|
29111
29767
|
let vectorStoreId;
|
|
29112
29768
|
// If knowledge sources are provided, create a vector store with them
|
|
29113
|
-
// TODO: [🧠] Reuse vector store creation logic from createNewAssistant
|
|
29114
29769
|
if (knowledgeSources && knowledgeSources.length > 0) {
|
|
29115
|
-
|
|
29116
|
-
|
|
29117
|
-
|
|
29118
|
-
|
|
29119
|
-
|
|
29120
|
-
});
|
|
29121
|
-
}
|
|
29122
|
-
// Create a vector store
|
|
29123
|
-
const vectorStore = await client.beta.vectorStores.create({
|
|
29124
|
-
name: `${name} Knowledge Base`,
|
|
29770
|
+
const vectorStoreResult = await this.createVectorStoreWithKnowledgeSources({
|
|
29771
|
+
client,
|
|
29772
|
+
name: name !== null && name !== void 0 ? name : assistantId,
|
|
29773
|
+
knowledgeSources,
|
|
29774
|
+
logLabel: 'assistant update',
|
|
29125
29775
|
});
|
|
29126
|
-
vectorStoreId =
|
|
29127
|
-
if (this.options.isVerbose) {
|
|
29128
|
-
console.info('[🤰]', 'Vector store created for assistant update', {
|
|
29129
|
-
vectorStoreId,
|
|
29130
|
-
});
|
|
29131
|
-
}
|
|
29132
|
-
// Upload files from knowledge sources to the vector store
|
|
29133
|
-
const fileStreams = [];
|
|
29134
|
-
for (const [index, source] of knowledgeSources.entries()) {
|
|
29135
|
-
try {
|
|
29136
|
-
if (this.options.isVerbose) {
|
|
29137
|
-
console.info('[🤰]', 'Processing knowledge source for update', {
|
|
29138
|
-
index: index + 1,
|
|
29139
|
-
total: knowledgeSources.length,
|
|
29140
|
-
source,
|
|
29141
|
-
sourceType: source.startsWith('http') || source.startsWith('https') ? 'url' : 'file',
|
|
29142
|
-
});
|
|
29143
|
-
}
|
|
29144
|
-
// Check if it's a URL
|
|
29145
|
-
if (source.startsWith('http://') || source.startsWith('https://')) {
|
|
29146
|
-
// Download the file
|
|
29147
|
-
const response = await fetch(source);
|
|
29148
|
-
if (!response.ok) {
|
|
29149
|
-
console.error(`Failed to download ${source}: ${response.statusText}`);
|
|
29150
|
-
continue;
|
|
29151
|
-
}
|
|
29152
|
-
const buffer = await response.arrayBuffer();
|
|
29153
|
-
let filename = source.split('/').pop() || 'downloaded-file';
|
|
29154
|
-
try {
|
|
29155
|
-
const url = new URL(source);
|
|
29156
|
-
filename = url.pathname.split('/').pop() || filename;
|
|
29157
|
-
}
|
|
29158
|
-
catch (error) {
|
|
29159
|
-
// Keep default filename
|
|
29160
|
-
}
|
|
29161
|
-
const blob = new Blob([buffer]);
|
|
29162
|
-
const file = new File([blob], filename);
|
|
29163
|
-
fileStreams.push(file);
|
|
29164
|
-
}
|
|
29165
|
-
else {
|
|
29166
|
-
/*
|
|
29167
|
-
TODO: [🐱🚀] Resolve problem with browser environment
|
|
29168
|
-
// Assume it's a local file path
|
|
29169
|
-
// Note: This will work in Node.js environment
|
|
29170
|
-
// For browser environments, this would need different handling
|
|
29171
|
-
const fs = await import('fs');
|
|
29172
|
-
const fileStream = fs.createReadStream(source);
|
|
29173
|
-
fileStreams.push(fileStream);
|
|
29174
|
-
*/
|
|
29175
|
-
}
|
|
29176
|
-
}
|
|
29177
|
-
catch (error) {
|
|
29178
|
-
console.error(`Error processing knowledge source ${source}:`, error);
|
|
29179
|
-
}
|
|
29180
|
-
}
|
|
29181
|
-
// Batch upload files to the vector store
|
|
29182
|
-
if (fileStreams.length > 0) {
|
|
29183
|
-
try {
|
|
29184
|
-
await client.beta.vectorStores.fileBatches.uploadAndPoll(vectorStoreId, {
|
|
29185
|
-
files: fileStreams,
|
|
29186
|
-
});
|
|
29187
|
-
if (this.options.isVerbose) {
|
|
29188
|
-
console.info('[🤰]', 'Uploaded files to vector store for update', {
|
|
29189
|
-
vectorStoreId,
|
|
29190
|
-
fileCount: fileStreams.length,
|
|
29191
|
-
});
|
|
29192
|
-
}
|
|
29193
|
-
}
|
|
29194
|
-
catch (error) {
|
|
29195
|
-
console.error('Error uploading files to vector store:', error);
|
|
29196
|
-
}
|
|
29197
|
-
}
|
|
29776
|
+
vectorStoreId = vectorStoreResult.vectorStoreId;
|
|
29198
29777
|
}
|
|
29199
29778
|
const assistantUpdate = {
|
|
29200
29779
|
name,
|
|
@@ -29237,7 +29816,7 @@ class OpenAiAssistantExecutionTools extends OpenAiExecutionTools {
|
|
|
29237
29816
|
* Discriminant for type guards
|
|
29238
29817
|
*/
|
|
29239
29818
|
get discriminant() {
|
|
29240
|
-
return DISCRIMINANT;
|
|
29819
|
+
return DISCRIMINANT$1;
|
|
29241
29820
|
}
|
|
29242
29821
|
/**
|
|
29243
29822
|
* Type guard to check if given `LlmExecutionTools` are instanceof `OpenAiAssistantExecutionTools`
|
|
@@ -29245,7 +29824,7 @@ class OpenAiAssistantExecutionTools extends OpenAiExecutionTools {
|
|
|
29245
29824
|
* Note: This is useful when you can possibly have multiple versions of `@promptbook/openai` installed
|
|
29246
29825
|
*/
|
|
29247
29826
|
static isOpenAiAssistantExecutionTools(llmExecutionTools) {
|
|
29248
|
-
return llmExecutionTools.discriminant === DISCRIMINANT;
|
|
29827
|
+
return llmExecutionTools.discriminant === DISCRIMINANT$1;
|
|
29249
29828
|
}
|
|
29250
29829
|
}
|
|
29251
29830
|
/**
|
|
@@ -29253,7 +29832,7 @@ class OpenAiAssistantExecutionTools extends OpenAiExecutionTools {
|
|
|
29253
29832
|
*
|
|
29254
29833
|
* @private const of `OpenAiAssistantExecutionTools`
|
|
29255
29834
|
*/
|
|
29256
|
-
const DISCRIMINANT = 'OPEN_AI_ASSISTANT_V1';
|
|
29835
|
+
const DISCRIMINANT$1 = 'OPEN_AI_ASSISTANT_V1';
|
|
29257
29836
|
/**
|
|
29258
29837
|
* TODO: !!!!! [✨🥚] Knowledge should work both with and without scrapers
|
|
29259
29838
|
* TODO: [🙎] In `OpenAiAssistantExecutionTools` Allow to create abstract assistants with `isCreatingNewAssistantsAllowed`
|
|
@@ -32060,206 +32639,425 @@ function promptbookifyAiText(text) {
|
|
|
32060
32639
|
* TODO: [🧠][✌️] Make some Promptbook-native token system
|
|
32061
32640
|
*/
|
|
32062
32641
|
|
|
32642
|
+
const DEFAULT_AGENT_KIT_MODEL_NAME = 'gpt-5.2';
|
|
32063
32643
|
/**
|
|
32064
|
-
* Execution
|
|
32644
|
+
* Execution tools for OpenAI AgentKit (Agents SDK).
|
|
32065
32645
|
*
|
|
32066
32646
|
* @public exported from `@promptbook/openai`
|
|
32067
32647
|
*/
|
|
32068
|
-
class
|
|
32648
|
+
class OpenAiAgentKitExecutionTools extends OpenAiVectorStoreHandler {
|
|
32649
|
+
/**
|
|
32650
|
+
* Creates OpenAI AgentKit execution tools.
|
|
32651
|
+
*/
|
|
32069
32652
|
constructor(options) {
|
|
32653
|
+
var _a;
|
|
32654
|
+
if (options.isProxied) {
|
|
32655
|
+
throw new NotYetImplementedError(`Proxy mode is not yet implemented for OpenAI AgentKit`);
|
|
32656
|
+
}
|
|
32070
32657
|
super(options);
|
|
32071
|
-
this.
|
|
32658
|
+
this.preparedAgentKitAgent = null;
|
|
32659
|
+
this.agentKitModelName = (_a = options.agentKitModelName) !== null && _a !== void 0 ? _a : DEFAULT_AGENT_KIT_MODEL_NAME;
|
|
32072
32660
|
}
|
|
32073
32661
|
get title() {
|
|
32074
|
-
return 'OpenAI
|
|
32662
|
+
return 'OpenAI AgentKit';
|
|
32075
32663
|
}
|
|
32076
32664
|
get description() {
|
|
32077
|
-
return 'Use OpenAI
|
|
32665
|
+
return 'Use OpenAI AgentKit for agent-style chat with tools and knowledge';
|
|
32078
32666
|
}
|
|
32079
32667
|
/**
|
|
32080
|
-
* Calls OpenAI
|
|
32668
|
+
* Calls OpenAI AgentKit with a chat prompt (non-streaming).
|
|
32669
|
+
*/
|
|
32670
|
+
async callChatModel(prompt) {
|
|
32671
|
+
return this.callChatModelStream(prompt, () => { });
|
|
32672
|
+
}
|
|
32673
|
+
/**
|
|
32674
|
+
* Calls OpenAI AgentKit with a chat prompt (streaming).
|
|
32081
32675
|
*/
|
|
32082
32676
|
async callChatModelStream(prompt, onProgress) {
|
|
32083
|
-
if (this.options.isVerbose) {
|
|
32084
|
-
console.info('💬 OpenAI Agent callChatModel call', { prompt });
|
|
32085
|
-
}
|
|
32086
32677
|
const { content, parameters, modelRequirements } = prompt;
|
|
32087
|
-
const client = await this.getClient();
|
|
32088
32678
|
if (modelRequirements.modelVariant !== 'CHAT') {
|
|
32089
32679
|
throw new PipelineExecutionError('Use callChatModel only for CHAT variant');
|
|
32090
32680
|
}
|
|
32681
|
+
for (const key of ['maxTokens', 'modelName', 'seed', 'temperature']) {
|
|
32682
|
+
if (modelRequirements[key] !== undefined) {
|
|
32683
|
+
throw new NotYetImplementedError(`In \`OpenAiAgentKitExecutionTools\` you cannot specify \`${key}\``);
|
|
32684
|
+
}
|
|
32685
|
+
}
|
|
32091
32686
|
const rawPromptContent = templateParameters(content, {
|
|
32092
32687
|
...parameters,
|
|
32093
|
-
modelName:
|
|
32688
|
+
modelName: this.agentKitModelName,
|
|
32094
32689
|
});
|
|
32095
|
-
|
|
32096
|
-
|
|
32097
|
-
|
|
32098
|
-
|
|
32099
|
-
|
|
32100
|
-
role: msg.sender === 'assistant' ? 'assistant' : 'user',
|
|
32101
|
-
content: msg.content,
|
|
32102
|
-
}));
|
|
32103
|
-
input.push(...previousMessages);
|
|
32104
|
-
}
|
|
32105
|
-
// Add current user message
|
|
32106
|
-
input.push({
|
|
32107
|
-
role: 'user',
|
|
32108
|
-
content: rawPromptContent,
|
|
32690
|
+
const preparedAgentKitAgent = await this.prepareAgentKitAgent({
|
|
32691
|
+
name: (prompt.title || 'Agent'),
|
|
32692
|
+
instructions: modelRequirements.systemMessage || '',
|
|
32693
|
+
knowledgeSources: modelRequirements.knowledgeSources,
|
|
32694
|
+
tools: 'tools' in prompt && Array.isArray(prompt.tools) ? prompt.tools : modelRequirements.tools,
|
|
32109
32695
|
});
|
|
32110
|
-
|
|
32111
|
-
|
|
32112
|
-
|
|
32113
|
-
|
|
32114
|
-
|
|
32115
|
-
|
|
32116
|
-
|
|
32117
|
-
|
|
32118
|
-
|
|
32119
|
-
|
|
32120
|
-
|
|
32121
|
-
|
|
32696
|
+
return this.callChatModelStreamWithPreparedAgent({
|
|
32697
|
+
openAiAgentKitAgent: preparedAgentKitAgent.agent,
|
|
32698
|
+
prompt,
|
|
32699
|
+
rawPromptContent,
|
|
32700
|
+
onProgress,
|
|
32701
|
+
});
|
|
32702
|
+
}
|
|
32703
|
+
/**
|
|
32704
|
+
* Returns a prepared AgentKit agent when the server wants to manage caching externally.
|
|
32705
|
+
*/
|
|
32706
|
+
getPreparedAgentKitAgent() {
|
|
32707
|
+
return this.preparedAgentKitAgent;
|
|
32708
|
+
}
|
|
32709
|
+
/**
|
|
32710
|
+
* Stores a prepared AgentKit agent for later reuse by external cache managers.
|
|
32711
|
+
*/
|
|
32712
|
+
setPreparedAgentKitAgent(preparedAgent) {
|
|
32713
|
+
this.preparedAgentKitAgent = preparedAgent;
|
|
32714
|
+
}
|
|
32715
|
+
/**
|
|
32716
|
+
* Creates a new tools instance bound to a prepared AgentKit agent.
|
|
32717
|
+
*/
|
|
32718
|
+
getPreparedAgentTools(preparedAgent) {
|
|
32719
|
+
const tools = new OpenAiAgentKitExecutionTools(this.agentKitOptions);
|
|
32720
|
+
tools.setPreparedAgentKitAgent(preparedAgent);
|
|
32721
|
+
return tools;
|
|
32722
|
+
}
|
|
32723
|
+
/**
|
|
32724
|
+
* Prepares an AgentKit agent with optional knowledge sources and tool definitions.
|
|
32725
|
+
*/
|
|
32726
|
+
async prepareAgentKitAgent(options) {
|
|
32727
|
+
var _a, _b;
|
|
32728
|
+
const { name, instructions, knowledgeSources, tools, vectorStoreId: cachedVectorStoreId, storeAsPrepared, } = options;
|
|
32729
|
+
await this.ensureAgentKitDefaults();
|
|
32730
|
+
if (this.options.isVerbose) {
|
|
32731
|
+
console.info('[🤰]', 'Preparing OpenAI AgentKit agent', {
|
|
32732
|
+
name,
|
|
32733
|
+
instructionsLength: instructions.length,
|
|
32734
|
+
knowledgeSourcesCount: (_a = knowledgeSources === null || knowledgeSources === void 0 ? void 0 : knowledgeSources.length) !== null && _a !== void 0 ? _a : 0,
|
|
32735
|
+
toolsCount: (_b = tools === null || tools === void 0 ? void 0 : tools.length) !== null && _b !== void 0 ? _b : 0,
|
|
32736
|
+
});
|
|
32122
32737
|
}
|
|
32123
|
-
|
|
32124
|
-
if (
|
|
32125
|
-
|
|
32126
|
-
|
|
32127
|
-
|
|
32128
|
-
|
|
32129
|
-
|
|
32130
|
-
|
|
32738
|
+
let vectorStoreId = cachedVectorStoreId;
|
|
32739
|
+
if (!vectorStoreId && knowledgeSources && knowledgeSources.length > 0) {
|
|
32740
|
+
const vectorStoreResult = await this.createVectorStoreWithKnowledgeSources({
|
|
32741
|
+
client: await this.getClient(),
|
|
32742
|
+
name,
|
|
32743
|
+
knowledgeSources,
|
|
32744
|
+
logLabel: 'agentkit preparation',
|
|
32745
|
+
});
|
|
32746
|
+
vectorStoreId = vectorStoreResult.vectorStoreId;
|
|
32131
32747
|
}
|
|
32132
|
-
|
|
32133
|
-
|
|
32134
|
-
|
|
32135
|
-
|
|
32136
|
-
|
|
32137
|
-
|
|
32138
|
-
|
|
32139
|
-
|
|
32140
|
-
|
|
32141
|
-
|
|
32748
|
+
else if (vectorStoreId && this.options.isVerbose) {
|
|
32749
|
+
console.info('[🤰]', 'Using cached vector store for AgentKit agent', {
|
|
32750
|
+
name,
|
|
32751
|
+
vectorStoreId,
|
|
32752
|
+
});
|
|
32753
|
+
}
|
|
32754
|
+
const agentKitTools = this.buildAgentKitTools({ tools, vectorStoreId });
|
|
32755
|
+
const openAiAgentKitAgent = new Agent$1({
|
|
32756
|
+
name,
|
|
32757
|
+
model: this.agentKitModelName,
|
|
32758
|
+
instructions: instructions || 'You are a helpful assistant.',
|
|
32759
|
+
tools: agentKitTools,
|
|
32760
|
+
});
|
|
32761
|
+
const preparedAgent = {
|
|
32762
|
+
agent: openAiAgentKitAgent,
|
|
32763
|
+
vectorStoreId,
|
|
32142
32764
|
};
|
|
32143
|
-
if (
|
|
32144
|
-
|
|
32765
|
+
if (storeAsPrepared) {
|
|
32766
|
+
this.setPreparedAgentKitAgent(preparedAgent);
|
|
32145
32767
|
}
|
|
32146
|
-
// Call Responses API
|
|
32147
|
-
// Note: Using any cast because types might not be updated yet
|
|
32148
|
-
const response = await client.responses.create(rawRequest);
|
|
32149
32768
|
if (this.options.isVerbose) {
|
|
32150
|
-
console.info(
|
|
32769
|
+
console.info('[🤰]', 'OpenAI AgentKit agent ready', {
|
|
32770
|
+
name,
|
|
32771
|
+
model: this.agentKitModelName,
|
|
32772
|
+
toolCount: agentKitTools.length,
|
|
32773
|
+
hasVectorStore: Boolean(vectorStoreId),
|
|
32774
|
+
});
|
|
32151
32775
|
}
|
|
32152
|
-
|
|
32153
|
-
|
|
32154
|
-
|
|
32155
|
-
|
|
32156
|
-
|
|
32157
|
-
|
|
32158
|
-
|
|
32159
|
-
|
|
32160
|
-
|
|
32161
|
-
|
|
32162
|
-
|
|
32776
|
+
return preparedAgent;
|
|
32777
|
+
}
|
|
32778
|
+
/**
|
|
32779
|
+
* Ensures the AgentKit SDK is wired to the OpenAI client and API key.
|
|
32780
|
+
*/
|
|
32781
|
+
async ensureAgentKitDefaults() {
|
|
32782
|
+
const client = await this.getClient();
|
|
32783
|
+
setDefaultOpenAIClient(client);
|
|
32784
|
+
const apiKey = this.agentKitOptions.apiKey;
|
|
32785
|
+
if (apiKey && typeof apiKey === 'string') {
|
|
32786
|
+
setDefaultOpenAIKey(apiKey);
|
|
32787
|
+
}
|
|
32788
|
+
}
|
|
32789
|
+
/**
|
|
32790
|
+
* Builds the tool list for AgentKit, including hosted file search when applicable.
|
|
32791
|
+
*/
|
|
32792
|
+
buildAgentKitTools(options) {
|
|
32793
|
+
var _a;
|
|
32794
|
+
const { tools, vectorStoreId } = options;
|
|
32795
|
+
const agentKitTools = [];
|
|
32796
|
+
if (vectorStoreId) {
|
|
32797
|
+
agentKitTools.push(fileSearchTool(vectorStoreId));
|
|
32798
|
+
}
|
|
32799
|
+
if (tools && tools.length > 0) {
|
|
32800
|
+
const scriptTools = this.resolveScriptTools();
|
|
32801
|
+
for (const toolDefinition of tools) {
|
|
32802
|
+
agentKitTools.push(tool({
|
|
32803
|
+
name: toolDefinition.name,
|
|
32804
|
+
description: toolDefinition.description,
|
|
32805
|
+
parameters: toolDefinition.parameters
|
|
32806
|
+
? {
|
|
32807
|
+
...toolDefinition.parameters,
|
|
32808
|
+
additionalProperties: false,
|
|
32809
|
+
required: (_a = toolDefinition.parameters.required) !== null && _a !== void 0 ? _a : [],
|
|
32810
|
+
}
|
|
32811
|
+
: undefined,
|
|
32812
|
+
strict: false,
|
|
32813
|
+
execute: async (input, runContext, details) => {
|
|
32814
|
+
var _a, _b, _c;
|
|
32815
|
+
const scriptTool = scriptTools[0];
|
|
32816
|
+
const functionName = toolDefinition.name;
|
|
32817
|
+
const calledAt = $getCurrentDate();
|
|
32818
|
+
const callId = (_a = details === null || details === void 0 ? void 0 : details.toolCall) === null || _a === void 0 ? void 0 : _a.callId;
|
|
32819
|
+
const functionArgs = input !== null && input !== void 0 ? input : {};
|
|
32820
|
+
if (this.options.isVerbose) {
|
|
32821
|
+
console.info('[🤰]', 'Executing AgentKit tool', {
|
|
32822
|
+
functionName,
|
|
32823
|
+
callId,
|
|
32824
|
+
calledAt,
|
|
32825
|
+
});
|
|
32163
32826
|
}
|
|
32164
|
-
|
|
32165
|
-
|
|
32827
|
+
try {
|
|
32828
|
+
return await scriptTool.execute({
|
|
32829
|
+
scriptLanguage: 'javascript',
|
|
32830
|
+
script: `
|
|
32831
|
+
const args = ${JSON.stringify(functionArgs)};
|
|
32832
|
+
return await ${functionName}(args);
|
|
32833
|
+
`,
|
|
32834
|
+
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 : {},
|
|
32835
|
+
});
|
|
32836
|
+
}
|
|
32837
|
+
catch (error) {
|
|
32838
|
+
assertsError(error);
|
|
32839
|
+
const serializedError = serializeError(error);
|
|
32840
|
+
const errorMessage = spaceTrim$2((block) => `
|
|
32841
|
+
|
|
32842
|
+
The invoked tool \`${functionName}\` failed with error:
|
|
32843
|
+
|
|
32844
|
+
\`\`\`json
|
|
32845
|
+
${block(JSON.stringify(serializedError, null, 4))}
|
|
32846
|
+
\`\`\`
|
|
32847
|
+
|
|
32848
|
+
`);
|
|
32849
|
+
console.error('[🤰]', 'AgentKit tool execution failed', {
|
|
32850
|
+
functionName,
|
|
32851
|
+
callId,
|
|
32852
|
+
error: serializedError,
|
|
32853
|
+
});
|
|
32854
|
+
return errorMessage;
|
|
32166
32855
|
}
|
|
32856
|
+
},
|
|
32857
|
+
}));
|
|
32858
|
+
}
|
|
32859
|
+
}
|
|
32860
|
+
return agentKitTools;
|
|
32861
|
+
}
|
|
32862
|
+
/**
|
|
32863
|
+
* Resolves the configured script tools for tool execution.
|
|
32864
|
+
*/
|
|
32865
|
+
resolveScriptTools() {
|
|
32866
|
+
const executionTools = this.options.executionTools;
|
|
32867
|
+
if (!executionTools || !executionTools.script) {
|
|
32868
|
+
throw new PipelineExecutionError(`Model requested tools but no executionTools.script were provided in OpenAiAgentKitExecutionTools options`);
|
|
32869
|
+
}
|
|
32870
|
+
return Array.isArray(executionTools.script) ? executionTools.script : [executionTools.script];
|
|
32871
|
+
}
|
|
32872
|
+
/**
|
|
32873
|
+
* Runs a prepared AgentKit agent and streams results back to the caller.
|
|
32874
|
+
*/
|
|
32875
|
+
async callChatModelStreamWithPreparedAgent(options) {
|
|
32876
|
+
var _a, _b, _c, _d;
|
|
32877
|
+
const { openAiAgentKitAgent, prompt, onProgress } = options;
|
|
32878
|
+
const rawPromptContent = (_a = options.rawPromptContent) !== null && _a !== void 0 ? _a : templateParameters(prompt.content, {
|
|
32879
|
+
...prompt.parameters,
|
|
32880
|
+
modelName: this.agentKitModelName,
|
|
32881
|
+
});
|
|
32882
|
+
const start = $getCurrentDate();
|
|
32883
|
+
let latestContent = '';
|
|
32884
|
+
const toolCalls = [];
|
|
32885
|
+
const toolCallIndexById = new Map();
|
|
32886
|
+
const inputItems = await this.buildAgentKitInputItems(prompt, rawPromptContent);
|
|
32887
|
+
const rawRequest = {
|
|
32888
|
+
agentName: openAiAgentKitAgent.name,
|
|
32889
|
+
input: inputItems,
|
|
32890
|
+
};
|
|
32891
|
+
const streamResult = await run(openAiAgentKitAgent, inputItems, {
|
|
32892
|
+
stream: true,
|
|
32893
|
+
context: { parameters: prompt.parameters },
|
|
32894
|
+
});
|
|
32895
|
+
for await (const event of streamResult) {
|
|
32896
|
+
if (event.type === 'raw_model_stream_event' && ((_b = event.data) === null || _b === void 0 ? void 0 : _b.type) === 'output_text_delta') {
|
|
32897
|
+
latestContent += event.data.delta;
|
|
32898
|
+
onProgress({
|
|
32899
|
+
content: latestContent,
|
|
32900
|
+
modelName: this.agentKitModelName,
|
|
32901
|
+
timing: { start, complete: $getCurrentDate() },
|
|
32902
|
+
usage: UNCERTAIN_USAGE,
|
|
32903
|
+
rawPromptContent: rawPromptContent,
|
|
32904
|
+
rawRequest: null,
|
|
32905
|
+
rawResponse: {},
|
|
32906
|
+
});
|
|
32907
|
+
continue;
|
|
32908
|
+
}
|
|
32909
|
+
if (event.type === 'run_item_stream_event') {
|
|
32910
|
+
const rawItem = (_c = event.item) === null || _c === void 0 ? void 0 : _c.rawItem;
|
|
32911
|
+
if (event.name === 'tool_called' && (rawItem === null || rawItem === void 0 ? void 0 : rawItem.type) === 'function_call') {
|
|
32912
|
+
const toolCall = {
|
|
32913
|
+
name: rawItem.name,
|
|
32914
|
+
arguments: rawItem.arguments,
|
|
32915
|
+
rawToolCall: rawItem,
|
|
32916
|
+
createdAt: $getCurrentDate(),
|
|
32917
|
+
};
|
|
32918
|
+
toolCallIndexById.set(rawItem.callId, toolCalls.length);
|
|
32919
|
+
toolCalls.push(toolCall);
|
|
32920
|
+
onProgress({
|
|
32921
|
+
content: latestContent,
|
|
32922
|
+
modelName: this.agentKitModelName,
|
|
32923
|
+
timing: { start, complete: $getCurrentDate() },
|
|
32924
|
+
usage: UNCERTAIN_USAGE,
|
|
32925
|
+
rawPromptContent: rawPromptContent,
|
|
32926
|
+
rawRequest: null,
|
|
32927
|
+
rawResponse: {},
|
|
32928
|
+
toolCalls: [toolCall],
|
|
32929
|
+
});
|
|
32930
|
+
}
|
|
32931
|
+
if (event.name === 'tool_output' && (rawItem === null || rawItem === void 0 ? void 0 : rawItem.type) === 'function_call_result') {
|
|
32932
|
+
const index = toolCallIndexById.get(rawItem.callId);
|
|
32933
|
+
const result = this.formatAgentKitToolOutput(rawItem.output);
|
|
32934
|
+
if (index !== undefined) {
|
|
32935
|
+
const existingToolCall = toolCalls[index];
|
|
32936
|
+
const completedToolCall = {
|
|
32937
|
+
...existingToolCall,
|
|
32938
|
+
result,
|
|
32939
|
+
rawToolCall: rawItem,
|
|
32940
|
+
};
|
|
32941
|
+
toolCalls[index] = completedToolCall;
|
|
32942
|
+
onProgress({
|
|
32943
|
+
content: latestContent,
|
|
32944
|
+
modelName: this.agentKitModelName,
|
|
32945
|
+
timing: { start, complete: $getCurrentDate() },
|
|
32946
|
+
usage: UNCERTAIN_USAGE,
|
|
32947
|
+
rawPromptContent: rawPromptContent,
|
|
32948
|
+
rawRequest: null,
|
|
32949
|
+
rawResponse: {},
|
|
32950
|
+
toolCalls: [completedToolCall],
|
|
32951
|
+
});
|
|
32167
32952
|
}
|
|
32168
32953
|
}
|
|
32169
|
-
else if (item.type === 'function_call') ;
|
|
32170
32954
|
}
|
|
32171
32955
|
}
|
|
32172
|
-
|
|
32173
|
-
|
|
32174
|
-
|
|
32175
|
-
|
|
32176
|
-
|
|
32177
|
-
|
|
32178
|
-
content: resultContent,
|
|
32179
|
-
modelName: response.model || 'agent',
|
|
32956
|
+
await streamResult.completed;
|
|
32957
|
+
const complete = $getCurrentDate();
|
|
32958
|
+
const finalContent = ((_d = streamResult.finalOutput) !== null && _d !== void 0 ? _d : latestContent);
|
|
32959
|
+
const finalResult = {
|
|
32960
|
+
content: finalContent,
|
|
32961
|
+
modelName: this.agentKitModelName,
|
|
32180
32962
|
timing: { start, complete },
|
|
32181
32963
|
usage: UNCERTAIN_USAGE,
|
|
32182
|
-
rawPromptContent,
|
|
32964
|
+
rawPromptContent: rawPromptContent,
|
|
32183
32965
|
rawRequest,
|
|
32184
|
-
rawResponse:
|
|
32185
|
-
|
|
32186
|
-
|
|
32187
|
-
|
|
32188
|
-
|
|
32189
|
-
order: [],
|
|
32190
|
-
value: {
|
|
32191
|
-
content: resultContent,
|
|
32192
|
-
modelName: response.model || 'agent',
|
|
32193
|
-
timing: { start, complete },
|
|
32194
|
-
usage: UNCERTAIN_USAGE,
|
|
32195
|
-
rawPromptContent,
|
|
32196
|
-
rawRequest,
|
|
32197
|
-
rawResponse: response,
|
|
32198
|
-
toolCalls: toolCalls.length > 0 ? toolCalls : undefined,
|
|
32199
|
-
},
|
|
32200
|
-
});
|
|
32966
|
+
rawResponse: { runResult: streamResult },
|
|
32967
|
+
toolCalls: toolCalls.length > 0 ? toolCalls : undefined,
|
|
32968
|
+
};
|
|
32969
|
+
onProgress(finalResult);
|
|
32970
|
+
return finalResult;
|
|
32201
32971
|
}
|
|
32202
32972
|
/**
|
|
32203
|
-
*
|
|
32973
|
+
* Builds AgentKit input items from the prompt and optional thread.
|
|
32204
32974
|
*/
|
|
32205
|
-
|
|
32206
|
-
|
|
32207
|
-
const
|
|
32208
|
-
|
|
32209
|
-
|
|
32210
|
-
|
|
32211
|
-
|
|
32212
|
-
|
|
32213
|
-
|
|
32214
|
-
|
|
32215
|
-
|
|
32216
|
-
|
|
32217
|
-
|
|
32218
|
-
const response = await fetch(source);
|
|
32219
|
-
if (!response.ok) {
|
|
32220
|
-
console.error(`Failed to download ${source}: ${response.statusText}`);
|
|
32221
|
-
continue;
|
|
32222
|
-
}
|
|
32223
|
-
const buffer = await response.arrayBuffer();
|
|
32224
|
-
const filename = source.split('/').pop() || 'downloaded-file';
|
|
32225
|
-
const blob = new Blob([buffer]);
|
|
32226
|
-
const file = new File([blob], filename);
|
|
32227
|
-
fileStreams.push(file);
|
|
32975
|
+
async buildAgentKitInputItems(prompt, rawPromptContent) {
|
|
32976
|
+
var _a;
|
|
32977
|
+
const inputItems = [];
|
|
32978
|
+
if ('thread' in prompt && Array.isArray(prompt.thread)) {
|
|
32979
|
+
for (const message of prompt.thread) {
|
|
32980
|
+
const sender = message.sender;
|
|
32981
|
+
const content = (_a = message.content) !== null && _a !== void 0 ? _a : '';
|
|
32982
|
+
if (sender === 'assistant' || sender === 'agent') {
|
|
32983
|
+
inputItems.push({
|
|
32984
|
+
role: 'assistant',
|
|
32985
|
+
status: 'completed',
|
|
32986
|
+
content: [{ type: 'output_text', text: content }],
|
|
32987
|
+
});
|
|
32228
32988
|
}
|
|
32229
32989
|
else {
|
|
32230
|
-
|
|
32990
|
+
inputItems.push({
|
|
32991
|
+
role: 'user',
|
|
32992
|
+
content,
|
|
32993
|
+
});
|
|
32231
32994
|
}
|
|
32232
32995
|
}
|
|
32233
|
-
catch (error) {
|
|
32234
|
-
console.error(`Error processing knowledge source ${source}:`, error);
|
|
32235
|
-
}
|
|
32236
32996
|
}
|
|
32237
|
-
|
|
32238
|
-
|
|
32239
|
-
|
|
32240
|
-
|
|
32241
|
-
|
|
32242
|
-
|
|
32243
|
-
|
|
32244
|
-
|
|
32245
|
-
|
|
32997
|
+
const userContent = await this.buildAgentKitUserContent(prompt, rawPromptContent);
|
|
32998
|
+
inputItems.push({
|
|
32999
|
+
role: 'user',
|
|
33000
|
+
content: userContent,
|
|
33001
|
+
});
|
|
33002
|
+
return inputItems;
|
|
33003
|
+
}
|
|
33004
|
+
/**
|
|
33005
|
+
* Builds the user message content for AgentKit runs, including file inputs when provided.
|
|
33006
|
+
*/
|
|
33007
|
+
async buildAgentKitUserContent(prompt, rawPromptContent) {
|
|
33008
|
+
if ('files' in prompt && Array.isArray(prompt.files) && prompt.files.length > 0) {
|
|
33009
|
+
const fileItems = await Promise.all(prompt.files.map(async (file) => {
|
|
33010
|
+
const arrayBuffer = await file.arrayBuffer();
|
|
33011
|
+
const base64 = Buffer.from(arrayBuffer).toString('base64');
|
|
33012
|
+
return {
|
|
33013
|
+
type: 'input_image',
|
|
33014
|
+
image: `data:${file.type};base64,${base64}`,
|
|
33015
|
+
};
|
|
33016
|
+
}));
|
|
33017
|
+
return [{ type: 'input_text', text: rawPromptContent }, ...fileItems];
|
|
33018
|
+
}
|
|
33019
|
+
return rawPromptContent;
|
|
33020
|
+
}
|
|
33021
|
+
/**
|
|
33022
|
+
* Normalizes AgentKit tool outputs into a string for Promptbook tool call results.
|
|
33023
|
+
*/
|
|
33024
|
+
formatAgentKitToolOutput(output) {
|
|
33025
|
+
if (typeof output === 'string') {
|
|
33026
|
+
return output;
|
|
33027
|
+
}
|
|
33028
|
+
if (output && typeof output === 'object') {
|
|
33029
|
+
const textOutput = output;
|
|
33030
|
+
if (textOutput.type === 'text' && typeof textOutput.text === 'string') {
|
|
33031
|
+
return textOutput.text;
|
|
32246
33032
|
}
|
|
32247
33033
|
}
|
|
32248
|
-
return
|
|
33034
|
+
return JSON.stringify(output !== null && output !== void 0 ? output : null);
|
|
32249
33035
|
}
|
|
32250
33036
|
/**
|
|
32251
|
-
*
|
|
33037
|
+
* Returns AgentKit-specific options.
|
|
33038
|
+
*/
|
|
33039
|
+
get agentKitOptions() {
|
|
33040
|
+
return this.options;
|
|
33041
|
+
}
|
|
33042
|
+
/**
|
|
33043
|
+
* Discriminant for type guards.
|
|
32252
33044
|
*/
|
|
32253
33045
|
get discriminant() {
|
|
32254
|
-
return
|
|
33046
|
+
return DISCRIMINANT;
|
|
32255
33047
|
}
|
|
32256
33048
|
/**
|
|
32257
|
-
* Type guard to check if given `LlmExecutionTools` are instanceof `
|
|
33049
|
+
* Type guard to check if given `LlmExecutionTools` are instanceof `OpenAiAgentKitExecutionTools`.
|
|
32258
33050
|
*/
|
|
32259
|
-
static
|
|
32260
|
-
return llmExecutionTools.discriminant ===
|
|
33051
|
+
static isOpenAiAgentKitExecutionTools(llmExecutionTools) {
|
|
33052
|
+
return llmExecutionTools.discriminant === DISCRIMINANT;
|
|
32261
33053
|
}
|
|
32262
33054
|
}
|
|
33055
|
+
/**
|
|
33056
|
+
* Discriminant for type guards.
|
|
33057
|
+
*
|
|
33058
|
+
* @private const of `OpenAiAgentKitExecutionTools`
|
|
33059
|
+
*/
|
|
33060
|
+
const DISCRIMINANT = 'OPEN_AI_AGENT_KIT_V1';
|
|
32263
33061
|
|
|
32264
33062
|
/**
|
|
32265
33063
|
* Emits a progress update to signal assistant preparation before long setup work.
|
|
@@ -32296,8 +33094,8 @@ function emitAssistantPreparationProgress(options) {
|
|
|
32296
33094
|
* - `Agent` - which represents an AI Agent with its source, memories, actions, etc. Agent is a higher-level abstraction which is internally using:
|
|
32297
33095
|
* - `LlmExecutionTools` - which wraps one or more LLM models and provides an interface to execute them
|
|
32298
33096
|
* - `AgentLlmExecutionTools` - which is a specific implementation of `LlmExecutionTools` that wraps another LlmExecutionTools and applies agent-specific system prompts and requirements
|
|
32299
|
-
* - `OpenAiAgentExecutionTools` - which is a specific implementation of `LlmExecutionTools` for OpenAI models with agent capabilities (using Responses API), recommended for usage in `Agent` or `AgentLlmExecutionTools`
|
|
32300
33097
|
* - `OpenAiAssistantExecutionTools` - (Deprecated) which is a specific implementation of `LlmExecutionTools` for OpenAI models with assistant capabilities
|
|
33098
|
+
* - `OpenAiAgentKitExecutionTools` - which is a specific implementation of `LlmExecutionTools` backed by OpenAI AgentKit
|
|
32301
33099
|
* - `RemoteAgent` - which is an `Agent` that connects to a Promptbook Agents Server
|
|
32302
33100
|
*
|
|
32303
33101
|
* @public exported from `@promptbook/core`
|
|
@@ -32432,6 +33230,7 @@ class AgentLlmExecutionTools {
|
|
|
32432
33230
|
* Calls the chat model with agent-specific system prompt and requirements with streaming
|
|
32433
33231
|
*/
|
|
32434
33232
|
async callChatModelStream(prompt, onProgress) {
|
|
33233
|
+
var _a, _b;
|
|
32435
33234
|
// Ensure we're working with a chat prompt
|
|
32436
33235
|
if (prompt.modelRequirements.modelVariant !== 'CHAT') {
|
|
32437
33236
|
throw new Error('AgentLlmExecutionTools only supports chat prompts');
|
|
@@ -32459,63 +33258,73 @@ class AgentLlmExecutionTools {
|
|
|
32459
33258
|
}, // Cast to avoid readonly mismatch from spread
|
|
32460
33259
|
};
|
|
32461
33260
|
console.log('!!!! promptWithAgentModelRequirements:', promptWithAgentModelRequirements);
|
|
32462
|
-
if (
|
|
33261
|
+
if (OpenAiAgentKitExecutionTools.isOpenAiAgentKitExecutionTools(this.options.llmTools)) {
|
|
32463
33262
|
const requirementsHash = SHA256(JSON.stringify(modelRequirements)).toString();
|
|
32464
|
-
const
|
|
32465
|
-
|
|
32466
|
-
|
|
33263
|
+
const vectorStoreHash = SHA256(JSON.stringify((_a = modelRequirements.knowledgeSources) !== null && _a !== void 0 ? _a : [])).toString();
|
|
33264
|
+
const cachedVectorStore = AgentLlmExecutionTools.vectorStoreCache.get(this.title);
|
|
33265
|
+
const cachedAgentKit = AgentLlmExecutionTools.agentKitAgentCache.get(this.title);
|
|
33266
|
+
let preparedAgentKit = this.options.assistantPreparationMode === 'external'
|
|
33267
|
+
? this.options.llmTools.getPreparedAgentKitAgent()
|
|
33268
|
+
: null;
|
|
33269
|
+
const vectorStoreId = (preparedAgentKit === null || preparedAgentKit === void 0 ? void 0 : preparedAgentKit.vectorStoreId) ||
|
|
33270
|
+
(cachedVectorStore && cachedVectorStore.requirementsHash === vectorStoreHash
|
|
33271
|
+
? cachedVectorStore.vectorStoreId
|
|
33272
|
+
: undefined);
|
|
33273
|
+
if (!preparedAgentKit && cachedAgentKit && cachedAgentKit.requirementsHash === requirementsHash) {
|
|
32467
33274
|
if (this.options.isVerbose) {
|
|
32468
|
-
console.
|
|
33275
|
+
console.info('[🤰]', 'Using cached OpenAI AgentKit agent', {
|
|
33276
|
+
agent: this.title,
|
|
33277
|
+
});
|
|
32469
33278
|
}
|
|
32470
|
-
|
|
32471
|
-
|
|
32472
|
-
|
|
32473
|
-
|
|
32474
|
-
// We can cast to access options if they were public, or use a method to clone.
|
|
32475
|
-
// OpenAiAgentExecutionTools doesn't have a clone method.
|
|
32476
|
-
// However, we can just assume the passed tool *might* not have the vector store yet, or we are replacing it.
|
|
32477
|
-
// Actually, if the passed tool IS OpenAiAgentExecutionTools, we should use it as a base.
|
|
32478
|
-
// TODO: [🧠] This is a bit hacky, accessing protected options or recreating tools.
|
|
32479
|
-
// Ideally OpenAiAgentExecutionTools should have a method `withVectorStoreId`.
|
|
32480
|
-
agentTools = new OpenAiAgentExecutionTools({
|
|
32481
|
-
...this.options.llmTools.options,
|
|
32482
|
-
vectorStoreId: cached.vectorStoreId,
|
|
32483
|
-
});
|
|
33279
|
+
preparedAgentKit = {
|
|
33280
|
+
agent: cachedAgentKit.agent,
|
|
33281
|
+
vectorStoreId: cachedAgentKit.vectorStoreId,
|
|
33282
|
+
};
|
|
32484
33283
|
}
|
|
32485
|
-
|
|
33284
|
+
if (!preparedAgentKit) {
|
|
32486
33285
|
if (this.options.isVerbose) {
|
|
32487
|
-
console.
|
|
32488
|
-
|
|
32489
|
-
|
|
32490
|
-
if (modelRequirements.knowledgeSources && modelRequirements.knowledgeSources.length > 0) {
|
|
32491
|
-
const client = await this.options.llmTools.getClient();
|
|
32492
|
-
vectorStoreId = await OpenAiAgentExecutionTools.createVectorStore(client, this.title, modelRequirements.knowledgeSources);
|
|
33286
|
+
console.info('[🤰]', 'Preparing OpenAI AgentKit agent', {
|
|
33287
|
+
agent: this.title,
|
|
33288
|
+
});
|
|
32493
33289
|
}
|
|
32494
|
-
if (vectorStoreId) {
|
|
32495
|
-
|
|
32496
|
-
|
|
32497
|
-
|
|
33290
|
+
if (!vectorStoreId && ((_b = modelRequirements.knowledgeSources) === null || _b === void 0 ? void 0 : _b.length)) {
|
|
33291
|
+
emitAssistantPreparationProgress({
|
|
33292
|
+
onProgress,
|
|
33293
|
+
prompt,
|
|
33294
|
+
modelName: this.modelName,
|
|
33295
|
+
phase: 'Creating knowledge base',
|
|
32498
33296
|
});
|
|
32499
33297
|
}
|
|
32500
|
-
|
|
32501
|
-
|
|
33298
|
+
emitAssistantPreparationProgress({
|
|
33299
|
+
onProgress,
|
|
33300
|
+
prompt,
|
|
33301
|
+
modelName: this.modelName,
|
|
33302
|
+
phase: 'Preparing AgentKit agent',
|
|
33303
|
+
});
|
|
33304
|
+
preparedAgentKit = await this.options.llmTools.prepareAgentKitAgent({
|
|
33305
|
+
name: this.title,
|
|
33306
|
+
instructions: modelRequirements.systemMessage || '',
|
|
33307
|
+
knowledgeSources: modelRequirements.knowledgeSources,
|
|
33308
|
+
tools: modelRequirements.tools ? [...modelRequirements.tools] : undefined,
|
|
32502
33309
|
vectorStoreId,
|
|
32503
33310
|
});
|
|
32504
33311
|
}
|
|
32505
|
-
|
|
32506
|
-
|
|
32507
|
-
|
|
32508
|
-
|
|
32509
|
-
|
|
32510
|
-
|
|
32511
|
-
|
|
32512
|
-
|
|
32513
|
-
|
|
32514
|
-
|
|
32515
|
-
|
|
32516
|
-
|
|
32517
|
-
|
|
32518
|
-
|
|
33312
|
+
if (preparedAgentKit.vectorStoreId) {
|
|
33313
|
+
AgentLlmExecutionTools.vectorStoreCache.set(this.title, {
|
|
33314
|
+
vectorStoreId: preparedAgentKit.vectorStoreId,
|
|
33315
|
+
requirementsHash: vectorStoreHash,
|
|
33316
|
+
});
|
|
33317
|
+
}
|
|
33318
|
+
AgentLlmExecutionTools.agentKitAgentCache.set(this.title, {
|
|
33319
|
+
agent: preparedAgentKit.agent,
|
|
33320
|
+
requirementsHash,
|
|
33321
|
+
vectorStoreId: preparedAgentKit.vectorStoreId,
|
|
33322
|
+
});
|
|
33323
|
+
underlyingLlmResult = await this.options.llmTools.callChatModelStreamWithPreparedAgent({
|
|
33324
|
+
openAiAgentKitAgent: preparedAgentKit.agent,
|
|
33325
|
+
prompt: promptWithAgentModelRequirements,
|
|
33326
|
+
onProgress,
|
|
33327
|
+
});
|
|
32519
33328
|
}
|
|
32520
33329
|
else if (OpenAiAssistantExecutionTools.isOpenAiAssistantExecutionTools(this.options.llmTools)) {
|
|
32521
33330
|
// ... deprecated path ...
|
|
@@ -32642,6 +33451,10 @@ class AgentLlmExecutionTools {
|
|
|
32642
33451
|
return agentResult;
|
|
32643
33452
|
}
|
|
32644
33453
|
}
|
|
33454
|
+
/**
|
|
33455
|
+
* Cached AgentKit agents to avoid rebuilding identical instances.
|
|
33456
|
+
*/
|
|
33457
|
+
AgentLlmExecutionTools.agentKitAgentCache = new Map();
|
|
32645
33458
|
/**
|
|
32646
33459
|
* Cache of OpenAI assistants to avoid creating duplicates
|
|
32647
33460
|
*/
|
|
@@ -32722,8 +33535,8 @@ function buildTeacherSummary(commitments, used) {
|
|
|
32722
33535
|
* - `Agent` - which represents an AI Agent with its source, memories, actions, etc. Agent is a higher-level abstraction which is internally using:
|
|
32723
33536
|
* - `LlmExecutionTools` - which wraps one or more LLM models and provides an interface to execute them
|
|
32724
33537
|
* - `AgentLlmExecutionTools` - which is a specific implementation of `LlmExecutionTools` that wraps another LlmExecutionTools and applies agent-specific system prompts and requirements
|
|
32725
|
-
* - `OpenAiAgentExecutionTools` - which is a specific implementation of `LlmExecutionTools` for OpenAI models with agent capabilities (using Responses API), recommended for usage in `Agent` or `AgentLlmExecutionTools`
|
|
32726
33538
|
* - `OpenAiAssistantExecutionTools` - (Deprecated) which is a specific implementation of `LlmExecutionTools` for OpenAI models with assistant capabilities
|
|
33539
|
+
* - `OpenAiAgentKitExecutionTools` - which is a specific implementation of `LlmExecutionTools` backed by OpenAI AgentKit
|
|
32727
33540
|
* - `RemoteAgent` - which is an `Agent` that connects to a Promptbook Agents Server
|
|
32728
33541
|
*
|
|
32729
33542
|
* @public exported from `@promptbook/core`
|
|
@@ -33094,7 +33907,8 @@ function buildRemoteAgentSource(profile, meta) {
|
|
|
33094
33907
|
* - `Agent` - which represents an AI Agent with its source, memories, actions, etc. Agent is a higher-level abstraction which is internally using:
|
|
33095
33908
|
* - `LlmExecutionTools` - which wraps one or more LLM models and provides an interface to execute them
|
|
33096
33909
|
* - `AgentLlmExecutionTools` - which is a specific implementation of `LlmExecutionTools` that wraps another LlmExecutionTools and applies agent-specific system prompts and requirements
|
|
33097
|
-
* - `OpenAiAssistantExecutionTools` - which is a specific implementation of `LlmExecutionTools` for OpenAI models with assistant capabilities
|
|
33910
|
+
* - `OpenAiAssistantExecutionTools` - (Deprecated) which is a specific implementation of `LlmExecutionTools` for OpenAI models with assistant capabilities
|
|
33911
|
+
* - `OpenAiAgentKitExecutionTools` - which is a specific implementation of `LlmExecutionTools` backed by OpenAI AgentKit
|
|
33098
33912
|
* - `RemoteAgent` - which is an `Agent` that connects to a Promptbook Agents Server
|
|
33099
33913
|
*
|
|
33100
33914
|
* @public exported from `@promptbook/core`
|