@promptbook/openai 0.98.0-5 → 0.98.0-8
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 +566 -4
- package/esm/index.es.js.map +1 -1
- package/esm/typings/src/_packages/anthropic-claude.index.d.ts +2 -2
- package/esm/typings/src/_packages/openai.index.d.ts +4 -0
- package/esm/typings/src/_packages/types.index.d.ts +10 -2
- package/esm/typings/src/config.d.ts +1 -1
- package/esm/typings/src/execution/createPipelineExecutor/$OngoingTaskResult.d.ts +1 -0
- package/esm/typings/src/execution/utils/validatePromptResult.d.ts +53 -0
- package/esm/typings/src/llm-providers/anthropic-claude/AnthropicClaudeExecutionTools.d.ts +3 -3
- package/esm/typings/src/llm-providers/anthropic-claude/AnthropicClaudeExecutionToolsOptions.d.ts +2 -2
- package/esm/typings/src/llm-providers/openai/OpenAiCompatibleExecutionTools.d.ts +4 -4
- package/esm/typings/src/llm-providers/openai/OpenAiCompatibleExecutionToolsOptions.d.ts +42 -1
- package/esm/typings/src/llm-providers/openai/createOpenAiCompatibleExecutionTools.d.ts +58 -1
- package/esm/typings/src/version.d.ts +1 -1
- package/package.json +3 -2
- package/umd/index.umd.js +569 -8
- package/umd/index.umd.js.map +1 -1
package/esm/index.es.js
CHANGED
|
@@ -3,6 +3,7 @@ import spaceTrim$1, { spaceTrim } from 'spacetrim';
|
|
|
3
3
|
import { randomBytes } from 'crypto';
|
|
4
4
|
import Bottleneck from 'bottleneck';
|
|
5
5
|
import OpenAI from 'openai';
|
|
6
|
+
import { io } from 'socket.io-client';
|
|
6
7
|
|
|
7
8
|
// ⚠️ WARNING: This code has been generated so that any manual changes will be overwritten
|
|
8
9
|
/**
|
|
@@ -18,7 +19,7 @@ const BOOK_LANGUAGE_VERSION = '1.0.0';
|
|
|
18
19
|
* @generated
|
|
19
20
|
* @see https://github.com/webgptorg/promptbook
|
|
20
21
|
*/
|
|
21
|
-
const PROMPTBOOK_ENGINE_VERSION = '0.98.0-
|
|
22
|
+
const PROMPTBOOK_ENGINE_VERSION = '0.98.0-8';
|
|
22
23
|
/**
|
|
23
24
|
* TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
|
|
24
25
|
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
@@ -276,6 +277,19 @@ const VALUE_STRINGS = {
|
|
|
276
277
|
* @public exported from `@promptbook/utils`
|
|
277
278
|
*/
|
|
278
279
|
const SMALL_NUMBER = 0.001;
|
|
280
|
+
/**
|
|
281
|
+
* Timeout for the connections in milliseconds
|
|
282
|
+
*
|
|
283
|
+
* @private within the repository - too low-level in comparison with other `MAX_...`
|
|
284
|
+
*/
|
|
285
|
+
const CONNECTION_TIMEOUT_MS = 7 * 1000;
|
|
286
|
+
// <- TODO: [⏳] Standardize timeouts, Make DEFAULT_TIMEOUT_MS as global constant
|
|
287
|
+
/**
|
|
288
|
+
* How many times to retry the connections
|
|
289
|
+
*
|
|
290
|
+
* @private within the repository - too low-level in comparison with other `MAX_...`
|
|
291
|
+
*/
|
|
292
|
+
const CONNECTION_RETRIES_LIMIT = 5;
|
|
279
293
|
// <- TODO: [🧜♂️]
|
|
280
294
|
/**
|
|
281
295
|
* Default settings for parsing and generating CSV files in Promptbook.
|
|
@@ -1780,7 +1794,7 @@ resultContent, rawResponse) {
|
|
|
1780
1794
|
*/
|
|
1781
1795
|
|
|
1782
1796
|
/**
|
|
1783
|
-
* Execution Tools for calling OpenAI API or other
|
|
1797
|
+
* Execution Tools for calling OpenAI API or other OpenAI compatible provider
|
|
1784
1798
|
*
|
|
1785
1799
|
* @public exported from `@promptbook/openai`
|
|
1786
1800
|
*/
|
|
@@ -2148,7 +2162,7 @@ class OpenAiExecutionTools extends OpenAiCompatibleExecutionTools {
|
|
|
2148
2162
|
* Default model for chat variant.
|
|
2149
2163
|
*/
|
|
2150
2164
|
getDefaultChatModel() {
|
|
2151
|
-
return this.getDefaultModel('gpt-
|
|
2165
|
+
return this.getDefaultModel('gpt-4-turbo');
|
|
2152
2166
|
}
|
|
2153
2167
|
/**
|
|
2154
2168
|
* Default model for completion variant.
|
|
@@ -2178,6 +2192,9 @@ class OpenAiAssistantExecutionTools extends OpenAiExecutionTools {
|
|
|
2178
2192
|
* @param options which are relevant are directly passed to the OpenAI client
|
|
2179
2193
|
*/
|
|
2180
2194
|
constructor(options) {
|
|
2195
|
+
if (options.isProxied) {
|
|
2196
|
+
throw new NotYetImplementedError(`Proxy mode is not yet implemented for OpenAI assistants`);
|
|
2197
|
+
}
|
|
2181
2198
|
super(options);
|
|
2182
2199
|
this.assistantId = options.assistantId;
|
|
2183
2200
|
// TODO: [👱] Make limiter same as in `OpenAiExecutionTools`
|
|
@@ -2351,6 +2368,465 @@ const createOpenAiAssistantExecutionTools = Object.assign((options) => {
|
|
|
2351
2368
|
* TODO: [🎶] Naming "constructor" vs "creator" vs "factory"
|
|
2352
2369
|
*/
|
|
2353
2370
|
|
|
2371
|
+
/**
|
|
2372
|
+
* This error indicates problems parsing the format value
|
|
2373
|
+
*
|
|
2374
|
+
* For example, when the format value is not a valid JSON or CSV
|
|
2375
|
+
* This is not thrown directly but in extended classes
|
|
2376
|
+
*
|
|
2377
|
+
* @public exported from `@promptbook/core`
|
|
2378
|
+
*/
|
|
2379
|
+
class AbstractFormatError extends Error {
|
|
2380
|
+
// Note: To allow instanceof do not put here error `name`
|
|
2381
|
+
// public readonly name = 'AbstractFormatError';
|
|
2382
|
+
constructor(message) {
|
|
2383
|
+
super(message);
|
|
2384
|
+
Object.setPrototypeOf(this, AbstractFormatError.prototype);
|
|
2385
|
+
}
|
|
2386
|
+
}
|
|
2387
|
+
|
|
2388
|
+
/**
|
|
2389
|
+
* This error indicates problem with parsing of CSV
|
|
2390
|
+
*
|
|
2391
|
+
* @public exported from `@promptbook/core`
|
|
2392
|
+
*/
|
|
2393
|
+
class CsvFormatError extends AbstractFormatError {
|
|
2394
|
+
constructor(message) {
|
|
2395
|
+
super(message);
|
|
2396
|
+
this.name = 'CsvFormatError';
|
|
2397
|
+
Object.setPrototypeOf(this, CsvFormatError.prototype);
|
|
2398
|
+
}
|
|
2399
|
+
}
|
|
2400
|
+
|
|
2401
|
+
/**
|
|
2402
|
+
* AuthenticationError is thrown from login function which is dependency of remote server
|
|
2403
|
+
*
|
|
2404
|
+
* @public exported from `@promptbook/core`
|
|
2405
|
+
*/
|
|
2406
|
+
class AuthenticationError extends Error {
|
|
2407
|
+
constructor(message) {
|
|
2408
|
+
super(message);
|
|
2409
|
+
this.name = 'AuthenticationError';
|
|
2410
|
+
Object.setPrototypeOf(this, AuthenticationError.prototype);
|
|
2411
|
+
}
|
|
2412
|
+
}
|
|
2413
|
+
|
|
2414
|
+
/**
|
|
2415
|
+
* This error indicates that the pipeline collection cannot be properly loaded
|
|
2416
|
+
*
|
|
2417
|
+
* @public exported from `@promptbook/core`
|
|
2418
|
+
*/
|
|
2419
|
+
class CollectionError extends Error {
|
|
2420
|
+
constructor(message) {
|
|
2421
|
+
super(message);
|
|
2422
|
+
this.name = 'CollectionError';
|
|
2423
|
+
Object.setPrototypeOf(this, CollectionError.prototype);
|
|
2424
|
+
}
|
|
2425
|
+
}
|
|
2426
|
+
|
|
2427
|
+
/**
|
|
2428
|
+
* This error type indicates that you try to use a feature that is not available in the current environment
|
|
2429
|
+
*
|
|
2430
|
+
* @public exported from `@promptbook/core`
|
|
2431
|
+
*/
|
|
2432
|
+
class EnvironmentMismatchError extends Error {
|
|
2433
|
+
constructor(message) {
|
|
2434
|
+
super(message);
|
|
2435
|
+
this.name = 'EnvironmentMismatchError';
|
|
2436
|
+
Object.setPrototypeOf(this, EnvironmentMismatchError.prototype);
|
|
2437
|
+
}
|
|
2438
|
+
}
|
|
2439
|
+
|
|
2440
|
+
/**
|
|
2441
|
+
* This error occurs when some expectation is not met in the execution of the pipeline
|
|
2442
|
+
*
|
|
2443
|
+
* @public exported from `@promptbook/core`
|
|
2444
|
+
* Note: Do not throw this error, its reserved for `checkExpectations` and `createPipelineExecutor` and public ONLY to be serializable through remote server
|
|
2445
|
+
* Note: Always thrown in `checkExpectations` and catched in `createPipelineExecutor` and rethrown as `PipelineExecutionError`
|
|
2446
|
+
* Note: This is a kindof subtype of PipelineExecutionError
|
|
2447
|
+
*/
|
|
2448
|
+
class ExpectError extends Error {
|
|
2449
|
+
constructor(message) {
|
|
2450
|
+
super(message);
|
|
2451
|
+
this.name = 'ExpectError';
|
|
2452
|
+
Object.setPrototypeOf(this, ExpectError.prototype);
|
|
2453
|
+
}
|
|
2454
|
+
}
|
|
2455
|
+
|
|
2456
|
+
/**
|
|
2457
|
+
* This error indicates that the promptbook can not retrieve knowledge from external sources
|
|
2458
|
+
*
|
|
2459
|
+
* @public exported from `@promptbook/core`
|
|
2460
|
+
*/
|
|
2461
|
+
class KnowledgeScrapeError extends Error {
|
|
2462
|
+
constructor(message) {
|
|
2463
|
+
super(message);
|
|
2464
|
+
this.name = 'KnowledgeScrapeError';
|
|
2465
|
+
Object.setPrototypeOf(this, KnowledgeScrapeError.prototype);
|
|
2466
|
+
}
|
|
2467
|
+
}
|
|
2468
|
+
|
|
2469
|
+
/**
|
|
2470
|
+
* This error type indicates that some tools are missing for pipeline execution or preparation
|
|
2471
|
+
*
|
|
2472
|
+
* @public exported from `@promptbook/core`
|
|
2473
|
+
*/
|
|
2474
|
+
class MissingToolsError extends Error {
|
|
2475
|
+
constructor(message) {
|
|
2476
|
+
super(spaceTrim((block) => `
|
|
2477
|
+
${block(message)}
|
|
2478
|
+
|
|
2479
|
+
Note: You have probably forgot to provide some tools for pipeline execution or preparation
|
|
2480
|
+
|
|
2481
|
+
`));
|
|
2482
|
+
this.name = 'MissingToolsError';
|
|
2483
|
+
Object.setPrototypeOf(this, MissingToolsError.prototype);
|
|
2484
|
+
}
|
|
2485
|
+
}
|
|
2486
|
+
|
|
2487
|
+
/**
|
|
2488
|
+
* This error indicates that promptbook not found in the collection
|
|
2489
|
+
*
|
|
2490
|
+
* @public exported from `@promptbook/core`
|
|
2491
|
+
*/
|
|
2492
|
+
class NotFoundError extends Error {
|
|
2493
|
+
constructor(message) {
|
|
2494
|
+
super(message);
|
|
2495
|
+
this.name = 'NotFoundError';
|
|
2496
|
+
Object.setPrototypeOf(this, NotFoundError.prototype);
|
|
2497
|
+
}
|
|
2498
|
+
}
|
|
2499
|
+
|
|
2500
|
+
/**
|
|
2501
|
+
* This error indicates that the promptbook in a markdown format cannot be parsed into a valid promptbook object
|
|
2502
|
+
*
|
|
2503
|
+
* @public exported from `@promptbook/core`
|
|
2504
|
+
*/
|
|
2505
|
+
class ParseError extends Error {
|
|
2506
|
+
constructor(message) {
|
|
2507
|
+
super(message);
|
|
2508
|
+
this.name = 'ParseError';
|
|
2509
|
+
Object.setPrototypeOf(this, ParseError.prototype);
|
|
2510
|
+
}
|
|
2511
|
+
}
|
|
2512
|
+
/**
|
|
2513
|
+
* TODO: Maybe split `ParseError` and `ApplyError`
|
|
2514
|
+
*/
|
|
2515
|
+
|
|
2516
|
+
/**
|
|
2517
|
+
* This error indicates that the promptbook object has valid syntax (=can be parsed) but contains logical errors (like circular dependencies)
|
|
2518
|
+
*
|
|
2519
|
+
* @public exported from `@promptbook/core`
|
|
2520
|
+
*/
|
|
2521
|
+
class PipelineLogicError extends Error {
|
|
2522
|
+
constructor(message) {
|
|
2523
|
+
super(message);
|
|
2524
|
+
this.name = 'PipelineLogicError';
|
|
2525
|
+
Object.setPrototypeOf(this, PipelineLogicError.prototype);
|
|
2526
|
+
}
|
|
2527
|
+
}
|
|
2528
|
+
|
|
2529
|
+
/**
|
|
2530
|
+
* This error indicates errors in referencing promptbooks between each other
|
|
2531
|
+
*
|
|
2532
|
+
* @public exported from `@promptbook/core`
|
|
2533
|
+
*/
|
|
2534
|
+
class PipelineUrlError extends Error {
|
|
2535
|
+
constructor(message) {
|
|
2536
|
+
super(message);
|
|
2537
|
+
this.name = 'PipelineUrlError';
|
|
2538
|
+
Object.setPrototypeOf(this, PipelineUrlError.prototype);
|
|
2539
|
+
}
|
|
2540
|
+
}
|
|
2541
|
+
|
|
2542
|
+
/**
|
|
2543
|
+
* Error thrown when a fetch request fails
|
|
2544
|
+
*
|
|
2545
|
+
* @public exported from `@promptbook/core`
|
|
2546
|
+
*/
|
|
2547
|
+
class PromptbookFetchError extends Error {
|
|
2548
|
+
constructor(message) {
|
|
2549
|
+
super(message);
|
|
2550
|
+
this.name = 'PromptbookFetchError';
|
|
2551
|
+
Object.setPrototypeOf(this, PromptbookFetchError.prototype);
|
|
2552
|
+
}
|
|
2553
|
+
}
|
|
2554
|
+
|
|
2555
|
+
/**
|
|
2556
|
+
* Index of all custom errors
|
|
2557
|
+
*
|
|
2558
|
+
* @public exported from `@promptbook/core`
|
|
2559
|
+
*/
|
|
2560
|
+
const PROMPTBOOK_ERRORS = {
|
|
2561
|
+
AbstractFormatError,
|
|
2562
|
+
CsvFormatError,
|
|
2563
|
+
CollectionError,
|
|
2564
|
+
EnvironmentMismatchError,
|
|
2565
|
+
ExpectError,
|
|
2566
|
+
KnowledgeScrapeError,
|
|
2567
|
+
LimitReachedError,
|
|
2568
|
+
MissingToolsError,
|
|
2569
|
+
NotFoundError,
|
|
2570
|
+
NotYetImplementedError,
|
|
2571
|
+
ParseError,
|
|
2572
|
+
PipelineExecutionError,
|
|
2573
|
+
PipelineLogicError,
|
|
2574
|
+
PipelineUrlError,
|
|
2575
|
+
AuthenticationError,
|
|
2576
|
+
PromptbookFetchError,
|
|
2577
|
+
UnexpectedError,
|
|
2578
|
+
WrappedError,
|
|
2579
|
+
// TODO: [🪑]> VersionMismatchError,
|
|
2580
|
+
};
|
|
2581
|
+
/**
|
|
2582
|
+
* Index of all javascript errors
|
|
2583
|
+
*
|
|
2584
|
+
* @private for internal usage
|
|
2585
|
+
*/
|
|
2586
|
+
const COMMON_JAVASCRIPT_ERRORS = {
|
|
2587
|
+
Error,
|
|
2588
|
+
EvalError,
|
|
2589
|
+
RangeError,
|
|
2590
|
+
ReferenceError,
|
|
2591
|
+
SyntaxError,
|
|
2592
|
+
TypeError,
|
|
2593
|
+
URIError,
|
|
2594
|
+
AggregateError,
|
|
2595
|
+
/*
|
|
2596
|
+
Note: Not widely supported
|
|
2597
|
+
> InternalError,
|
|
2598
|
+
> ModuleError,
|
|
2599
|
+
> HeapError,
|
|
2600
|
+
> WebAssemblyCompileError,
|
|
2601
|
+
> WebAssemblyRuntimeError,
|
|
2602
|
+
*/
|
|
2603
|
+
};
|
|
2604
|
+
/**
|
|
2605
|
+
* Index of all errors
|
|
2606
|
+
*
|
|
2607
|
+
* @private for internal usage
|
|
2608
|
+
*/
|
|
2609
|
+
const ALL_ERRORS = {
|
|
2610
|
+
...PROMPTBOOK_ERRORS,
|
|
2611
|
+
...COMMON_JAVASCRIPT_ERRORS,
|
|
2612
|
+
};
|
|
2613
|
+
/**
|
|
2614
|
+
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
2615
|
+
*/
|
|
2616
|
+
|
|
2617
|
+
/**
|
|
2618
|
+
* Deserializes the error object
|
|
2619
|
+
*
|
|
2620
|
+
* @public exported from `@promptbook/utils`
|
|
2621
|
+
*/
|
|
2622
|
+
function deserializeError(error) {
|
|
2623
|
+
const { name, stack, id } = error; // Added id
|
|
2624
|
+
let { message } = error;
|
|
2625
|
+
let ErrorClass = ALL_ERRORS[error.name];
|
|
2626
|
+
if (ErrorClass === undefined) {
|
|
2627
|
+
ErrorClass = Error;
|
|
2628
|
+
message = `${name}: ${message}`;
|
|
2629
|
+
}
|
|
2630
|
+
if (stack !== undefined && stack !== '') {
|
|
2631
|
+
message = spaceTrim$1((block) => `
|
|
2632
|
+
${block(message)}
|
|
2633
|
+
|
|
2634
|
+
Original stack trace:
|
|
2635
|
+
${block(stack || '')}
|
|
2636
|
+
`);
|
|
2637
|
+
}
|
|
2638
|
+
const deserializedError = new ErrorClass(message);
|
|
2639
|
+
deserializedError.id = id; // Assign id to the error object
|
|
2640
|
+
return deserializedError;
|
|
2641
|
+
}
|
|
2642
|
+
|
|
2643
|
+
/**
|
|
2644
|
+
* Tests if given string is valid URL.
|
|
2645
|
+
*
|
|
2646
|
+
* Note: Dataurl are considered perfectly valid.
|
|
2647
|
+
* Note: There are two similar functions:
|
|
2648
|
+
* - `isValidUrl` which tests any URL
|
|
2649
|
+
* - `isValidPipelineUrl` *(this one)* which tests just promptbook URL
|
|
2650
|
+
*
|
|
2651
|
+
* @public exported from `@promptbook/utils`
|
|
2652
|
+
*/
|
|
2653
|
+
function isValidUrl(url) {
|
|
2654
|
+
if (typeof url !== 'string') {
|
|
2655
|
+
return false;
|
|
2656
|
+
}
|
|
2657
|
+
try {
|
|
2658
|
+
if (url.startsWith('blob:')) {
|
|
2659
|
+
url = url.replace(/^blob:/, '');
|
|
2660
|
+
}
|
|
2661
|
+
const urlObject = new URL(url /* because fail is handled */);
|
|
2662
|
+
if (!['http:', 'https:', 'data:'].includes(urlObject.protocol)) {
|
|
2663
|
+
return false;
|
|
2664
|
+
}
|
|
2665
|
+
return true;
|
|
2666
|
+
}
|
|
2667
|
+
catch (error) {
|
|
2668
|
+
return false;
|
|
2669
|
+
}
|
|
2670
|
+
}
|
|
2671
|
+
|
|
2672
|
+
/**
|
|
2673
|
+
* Creates a connection to the remote proxy server.
|
|
2674
|
+
*
|
|
2675
|
+
* Note: This function creates a connection to the remote server and returns a socket but responsibility of closing the connection is on the caller
|
|
2676
|
+
*
|
|
2677
|
+
* @private internal utility function
|
|
2678
|
+
*/
|
|
2679
|
+
async function createRemoteClient(options) {
|
|
2680
|
+
const { remoteServerUrl } = options;
|
|
2681
|
+
if (!isValidUrl(remoteServerUrl)) {
|
|
2682
|
+
throw new Error(`Invalid \`remoteServerUrl\`: "${remoteServerUrl}"`);
|
|
2683
|
+
}
|
|
2684
|
+
const remoteServerUrlParsed = new URL(remoteServerUrl);
|
|
2685
|
+
if (remoteServerUrlParsed.pathname !== '/' && remoteServerUrlParsed.pathname !== '') {
|
|
2686
|
+
remoteServerUrlParsed.pathname = '/';
|
|
2687
|
+
throw new Error(spaceTrim$1((block) => `
|
|
2688
|
+
Remote server requires root url \`/\`
|
|
2689
|
+
|
|
2690
|
+
You have provided \`remoteServerUrl\`:
|
|
2691
|
+
${block(remoteServerUrl)}
|
|
2692
|
+
|
|
2693
|
+
But something like this is expected:
|
|
2694
|
+
${block(remoteServerUrlParsed.href)}
|
|
2695
|
+
|
|
2696
|
+
Note: If you need to run multiple services on the same server, use 3rd or 4th degree subdomain
|
|
2697
|
+
|
|
2698
|
+
`));
|
|
2699
|
+
}
|
|
2700
|
+
return new Promise((resolve, reject) => {
|
|
2701
|
+
const socket = io(remoteServerUrl, {
|
|
2702
|
+
retries: CONNECTION_RETRIES_LIMIT,
|
|
2703
|
+
timeout: CONNECTION_TIMEOUT_MS,
|
|
2704
|
+
path: '/socket.io',
|
|
2705
|
+
transports: ['polling', 'websocket' /*, <- TODO: [🌬] Allow to pass `transports`, add 'webtransport' */],
|
|
2706
|
+
});
|
|
2707
|
+
// console.log('Connecting to', this.options.remoteServerUrl.href, { socket });
|
|
2708
|
+
socket.on('connect', () => {
|
|
2709
|
+
resolve(socket);
|
|
2710
|
+
});
|
|
2711
|
+
// TODO: [💩] Better timeout handling
|
|
2712
|
+
setTimeout(() => {
|
|
2713
|
+
reject(new Error(`Timeout while connecting to ${remoteServerUrl}`));
|
|
2714
|
+
}, CONNECTION_TIMEOUT_MS);
|
|
2715
|
+
});
|
|
2716
|
+
}
|
|
2717
|
+
|
|
2718
|
+
/**
|
|
2719
|
+
* Remote server is a proxy server that uses its execution tools internally and exposes the executor interface externally.
|
|
2720
|
+
*
|
|
2721
|
+
* You can simply use `RemoteExecutionTools` on client-side javascript and connect to your remote server.
|
|
2722
|
+
* This is useful to make all logic on browser side but not expose your API keys or no need to use customer's GPU.
|
|
2723
|
+
*
|
|
2724
|
+
* @see https://github.com/webgptorg/promptbook#remote-server
|
|
2725
|
+
* @public exported from `@promptbook/remote-client`
|
|
2726
|
+
*/
|
|
2727
|
+
class RemoteLlmExecutionTools {
|
|
2728
|
+
/* <- TODO: [🍚] `, Destroyable` */
|
|
2729
|
+
constructor(options) {
|
|
2730
|
+
this.options = options;
|
|
2731
|
+
}
|
|
2732
|
+
get title() {
|
|
2733
|
+
// TODO: [🧠] Maybe fetch title+description from the remote server (as well as if model methods are defined)
|
|
2734
|
+
return 'Promptbook remote server';
|
|
2735
|
+
}
|
|
2736
|
+
get description() {
|
|
2737
|
+
return `Models from Promptbook remote server ${this.options.remoteServerUrl}`;
|
|
2738
|
+
}
|
|
2739
|
+
/**
|
|
2740
|
+
* Check the configuration of all execution tools
|
|
2741
|
+
*/
|
|
2742
|
+
async checkConfiguration() {
|
|
2743
|
+
const socket = await createRemoteClient(this.options);
|
|
2744
|
+
socket.disconnect();
|
|
2745
|
+
// TODO: [main] !!3 Check version of the remote server and compatibility
|
|
2746
|
+
// TODO: [🎍] Send checkConfiguration
|
|
2747
|
+
}
|
|
2748
|
+
/**
|
|
2749
|
+
* List all available models that can be used
|
|
2750
|
+
*/
|
|
2751
|
+
async listModels() {
|
|
2752
|
+
// TODO: [👒] Listing models (and checking configuration) probably should go through REST API not Socket.io
|
|
2753
|
+
const socket = await createRemoteClient(this.options);
|
|
2754
|
+
socket.emit('listModels-request', {
|
|
2755
|
+
identification: this.options.identification,
|
|
2756
|
+
} /* <- Note: [🤛] */);
|
|
2757
|
+
const promptResult = await new Promise((resolve, reject) => {
|
|
2758
|
+
socket.on('listModels-response', (response) => {
|
|
2759
|
+
resolve(response.models);
|
|
2760
|
+
socket.disconnect();
|
|
2761
|
+
});
|
|
2762
|
+
socket.on('error', (error) => {
|
|
2763
|
+
reject(deserializeError(error));
|
|
2764
|
+
socket.disconnect();
|
|
2765
|
+
});
|
|
2766
|
+
});
|
|
2767
|
+
socket.disconnect();
|
|
2768
|
+
return promptResult;
|
|
2769
|
+
}
|
|
2770
|
+
/**
|
|
2771
|
+
* Calls remote proxy server to use a chat model
|
|
2772
|
+
*/
|
|
2773
|
+
callChatModel(prompt) {
|
|
2774
|
+
if (this.options.isVerbose) {
|
|
2775
|
+
console.info(`🖋 Remote callChatModel call`);
|
|
2776
|
+
}
|
|
2777
|
+
return /* not await */ this.callCommonModel(prompt);
|
|
2778
|
+
}
|
|
2779
|
+
/**
|
|
2780
|
+
* Calls remote proxy server to use a completion model
|
|
2781
|
+
*/
|
|
2782
|
+
callCompletionModel(prompt) {
|
|
2783
|
+
if (this.options.isVerbose) {
|
|
2784
|
+
console.info(`💬 Remote callCompletionModel call`);
|
|
2785
|
+
}
|
|
2786
|
+
return /* not await */ this.callCommonModel(prompt);
|
|
2787
|
+
}
|
|
2788
|
+
/**
|
|
2789
|
+
* Calls remote proxy server to use a embedding model
|
|
2790
|
+
*/
|
|
2791
|
+
callEmbeddingModel(prompt) {
|
|
2792
|
+
if (this.options.isVerbose) {
|
|
2793
|
+
console.info(`💬 Remote callEmbeddingModel call`);
|
|
2794
|
+
}
|
|
2795
|
+
return /* not await */ this.callCommonModel(prompt);
|
|
2796
|
+
}
|
|
2797
|
+
// <- Note: [🤖] callXxxModel
|
|
2798
|
+
/**
|
|
2799
|
+
* Calls remote proxy server to use both completion or chat model
|
|
2800
|
+
*/
|
|
2801
|
+
async callCommonModel(prompt) {
|
|
2802
|
+
const socket = await createRemoteClient(this.options);
|
|
2803
|
+
socket.emit('prompt-request', {
|
|
2804
|
+
identification: this.options.identification,
|
|
2805
|
+
prompt,
|
|
2806
|
+
} /* <- Note: [🤛] */);
|
|
2807
|
+
const promptResult = await new Promise((resolve, reject) => {
|
|
2808
|
+
socket.on('prompt-response', (response) => {
|
|
2809
|
+
resolve(response.promptResult);
|
|
2810
|
+
socket.disconnect();
|
|
2811
|
+
});
|
|
2812
|
+
socket.on('error', (error) => {
|
|
2813
|
+
reject(deserializeError(error));
|
|
2814
|
+
socket.disconnect();
|
|
2815
|
+
});
|
|
2816
|
+
});
|
|
2817
|
+
socket.disconnect();
|
|
2818
|
+
return promptResult;
|
|
2819
|
+
}
|
|
2820
|
+
}
|
|
2821
|
+
/**
|
|
2822
|
+
* TODO: Maybe use `$exportJson`
|
|
2823
|
+
* TODO: [🧠][🛍] Maybe not `isAnonymous: boolean` BUT `mode: 'ANONYMOUS'|'COLLECTION'`
|
|
2824
|
+
* TODO: [🍓] Allow to list compatible models with each variant
|
|
2825
|
+
* TODO: [🗯] RemoteLlmExecutionTools should extend Destroyable and implement IDestroyable
|
|
2826
|
+
* TODO: [🧠][🌰] Allow to pass `title` for tracking purposes
|
|
2827
|
+
* TODO: [🧠] Maybe remove `@promptbook/remote-client` and just use `@promptbook/core`
|
|
2828
|
+
*/
|
|
2829
|
+
|
|
2354
2830
|
/**
|
|
2355
2831
|
* Execution Tools for calling OpenAI compatible API
|
|
2356
2832
|
*
|
|
@@ -2359,14 +2835,97 @@ const createOpenAiAssistantExecutionTools = Object.assign((options) => {
|
|
|
2359
2835
|
* @public exported from `@promptbook/openai`
|
|
2360
2836
|
*/
|
|
2361
2837
|
const createOpenAiCompatibleExecutionTools = Object.assign((options) => {
|
|
2838
|
+
if (options.isProxied) {
|
|
2839
|
+
return new RemoteLlmExecutionTools({
|
|
2840
|
+
...options,
|
|
2841
|
+
identification: {
|
|
2842
|
+
isAnonymous: true,
|
|
2843
|
+
llmToolsConfiguration: [
|
|
2844
|
+
{
|
|
2845
|
+
title: 'OpenAI Compatible (proxied)',
|
|
2846
|
+
packageName: '@promptbook/openai',
|
|
2847
|
+
className: 'OpenAiCompatibleExecutionTools',
|
|
2848
|
+
options: {
|
|
2849
|
+
...options,
|
|
2850
|
+
isProxied: false,
|
|
2851
|
+
},
|
|
2852
|
+
},
|
|
2853
|
+
],
|
|
2854
|
+
},
|
|
2855
|
+
});
|
|
2856
|
+
}
|
|
2362
2857
|
if (($isRunningInBrowser() || $isRunningInWebWorker()) && !options.dangerouslyAllowBrowser) {
|
|
2363
2858
|
options = { ...options, dangerouslyAllowBrowser: true };
|
|
2364
2859
|
}
|
|
2365
|
-
return new
|
|
2860
|
+
return new HardcodedOpenAiCompatibleExecutionTools(options.defaultModelName, options);
|
|
2366
2861
|
}, {
|
|
2367
2862
|
packageName: '@promptbook/openai',
|
|
2368
2863
|
className: 'OpenAiCompatibleExecutionTools',
|
|
2369
2864
|
});
|
|
2865
|
+
/**
|
|
2866
|
+
* Execution Tools for calling ONE SPECIFIC PRECONFIGURED OpenAI compatible provider
|
|
2867
|
+
*
|
|
2868
|
+
* @private for `createOpenAiCompatibleExecutionTools`
|
|
2869
|
+
*/
|
|
2870
|
+
class HardcodedOpenAiCompatibleExecutionTools extends OpenAiCompatibleExecutionTools {
|
|
2871
|
+
/**
|
|
2872
|
+
* Creates OpenAI compatible Execution Tools.
|
|
2873
|
+
*
|
|
2874
|
+
* @param options which are relevant are directly passed to the OpenAI compatible client
|
|
2875
|
+
*/
|
|
2876
|
+
constructor(defaultModelName, options) {
|
|
2877
|
+
super(options);
|
|
2878
|
+
this.defaultModelName = defaultModelName;
|
|
2879
|
+
this.options = options;
|
|
2880
|
+
}
|
|
2881
|
+
get title() {
|
|
2882
|
+
return `${this.defaultModelName} on ${this.options.baseURL}`;
|
|
2883
|
+
}
|
|
2884
|
+
get description() {
|
|
2885
|
+
return `OpenAI compatible connected to "${this.options.baseURL}" model "${this.defaultModelName}"`;
|
|
2886
|
+
}
|
|
2887
|
+
/**
|
|
2888
|
+
* List all available models (non dynamically)
|
|
2889
|
+
*
|
|
2890
|
+
* Note: Purpose of this is to provide more information about models than standard listing from API
|
|
2891
|
+
*/
|
|
2892
|
+
get HARDCODED_MODELS() {
|
|
2893
|
+
return [
|
|
2894
|
+
{
|
|
2895
|
+
modelName: this.defaultModelName,
|
|
2896
|
+
modelVariant: 'CHAT',
|
|
2897
|
+
modelDescription: '', // <- TODO: What is the best value here, maybe `this.description`?
|
|
2898
|
+
},
|
|
2899
|
+
];
|
|
2900
|
+
}
|
|
2901
|
+
/**
|
|
2902
|
+
* Computes the usage
|
|
2903
|
+
*/
|
|
2904
|
+
computeUsage(...args) {
|
|
2905
|
+
return {
|
|
2906
|
+
...computeOpenAiUsage(...args),
|
|
2907
|
+
price: UNCERTAIN_ZERO_VALUE, // <- TODO: Maybe in future pass this counting mechanism, but for now, we dont know
|
|
2908
|
+
};
|
|
2909
|
+
}
|
|
2910
|
+
/**
|
|
2911
|
+
* Default model for chat variant.
|
|
2912
|
+
*/
|
|
2913
|
+
getDefaultChatModel() {
|
|
2914
|
+
return this.getDefaultModel(this.defaultModelName);
|
|
2915
|
+
}
|
|
2916
|
+
/**
|
|
2917
|
+
* Default model for completion variant.
|
|
2918
|
+
*/
|
|
2919
|
+
getDefaultCompletionModel() {
|
|
2920
|
+
throw new PipelineExecutionError(`${this.title} does not support COMPLETION model variant`);
|
|
2921
|
+
}
|
|
2922
|
+
/**
|
|
2923
|
+
* Default model for completion variant.
|
|
2924
|
+
*/
|
|
2925
|
+
getDefaultEmbeddingModel() {
|
|
2926
|
+
throw new PipelineExecutionError(`${this.title} does not support EMBEDDING model variant`);
|
|
2927
|
+
}
|
|
2928
|
+
}
|
|
2370
2929
|
/**
|
|
2371
2930
|
* TODO: [🦺] Is there some way how to put `packageName` and `className` on top and function definition on bottom?
|
|
2372
2931
|
* TODO: [🎶] Naming "constructor" vs "creator" vs "factory"
|
|
@@ -2383,6 +2942,9 @@ const createOpenAiExecutionTools = Object.assign((options) => {
|
|
|
2383
2942
|
if (($isRunningInBrowser() || $isRunningInWebWorker()) && !options.dangerouslyAllowBrowser) {
|
|
2384
2943
|
options = { ...options, dangerouslyAllowBrowser: true };
|
|
2385
2944
|
}
|
|
2945
|
+
if (options.isProxied) {
|
|
2946
|
+
throw new NotYetImplementedError(`Proxy mode is not yet implemented in createOpenAiExecutionTools`);
|
|
2947
|
+
}
|
|
2386
2948
|
return new OpenAiExecutionTools(options);
|
|
2387
2949
|
}, {
|
|
2388
2950
|
packageName: '@promptbook/openai',
|