@gammatech/aijsx 0.10.2-dev.2024-06-11 → 0.11.1-dev.2024-06-23
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/dist/index.d.mts +23 -8
- package/dist/index.d.ts +23 -8
- package/dist/index.js +150 -87
- package/dist/index.mjs +149 -87
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -13,8 +13,9 @@ declare class ChatCompletionError extends Error {
|
|
|
13
13
|
readonly chatCompletionRequest: LogChatCompletionRequest;
|
|
14
14
|
readonly status: number | undefined;
|
|
15
15
|
readonly shouldRetry: boolean;
|
|
16
|
+
readonly originalError?: Error | undefined;
|
|
16
17
|
readonly name = "ChatCompletionError";
|
|
17
|
-
constructor(message: string, chatCompletionRequest: LogChatCompletionRequest, status: number | undefined, shouldRetry?: boolean);
|
|
18
|
+
constructor(message: string, chatCompletionRequest: LogChatCompletionRequest, status: number | undefined, shouldRetry?: boolean, originalError?: Error | undefined);
|
|
18
19
|
}
|
|
19
20
|
|
|
20
21
|
declare const SystemMessage: (props: {
|
|
@@ -43,6 +44,10 @@ type ChatCompletionClientAndProvider<K> = {
|
|
|
43
44
|
completion: number;
|
|
44
45
|
}) => number;
|
|
45
46
|
};
|
|
47
|
+
type GetChatCompletionClientAndProvider<Model, Client> = (model: Model, args: {
|
|
48
|
+
retryCount: number;
|
|
49
|
+
lastError?: Error | null;
|
|
50
|
+
}) => Promise<ChatCompletionClientAndProvider<Client>>;
|
|
46
51
|
|
|
47
52
|
type CreateRenderContextOptions = {
|
|
48
53
|
logger?: LogImplementation;
|
|
@@ -52,15 +57,25 @@ type CreateRenderContextOptions = {
|
|
|
52
57
|
};
|
|
53
58
|
declare function createRenderContext({ logger, traceId, processor, contextValues, }?: CreateRenderContextOptions): RenderContext;
|
|
54
59
|
|
|
55
|
-
|
|
60
|
+
type ExcludeNumber<E extends number, T = number> = T extends E ? never : T;
|
|
61
|
+
type RetryCountContextValue = {
|
|
62
|
+
retryCount: 0;
|
|
63
|
+
lastError: null;
|
|
64
|
+
} | {
|
|
65
|
+
retryCount: ExcludeNumber<0>;
|
|
66
|
+
lastError: Error;
|
|
67
|
+
};
|
|
68
|
+
declare const RetryCountContext: Context<RetryCountContextValue>;
|
|
69
|
+
declare const RetryLastErrorContext: Context<Error | null>;
|
|
56
70
|
declare const DefaultMaxRetriesContext: Context<number>;
|
|
57
71
|
type RetryProps = {
|
|
58
72
|
shouldRetry: (error: Error) => boolean;
|
|
59
73
|
retries?: number;
|
|
74
|
+
lastError?: Error;
|
|
60
75
|
maxRetries?: number;
|
|
61
76
|
children: AINode;
|
|
62
77
|
};
|
|
63
|
-
declare function Retry({ shouldRetry, retries, maxRetries, children }: RetryProps, ctx: RenderContext): AsyncGenerator<string, void, unknown>;
|
|
78
|
+
declare function Retry({ shouldRetry, retries, maxRetries, lastError, children }: RetryProps, ctx: RenderContext): AsyncGenerator<string, void, unknown>;
|
|
64
79
|
|
|
65
80
|
type FallbackProps = {
|
|
66
81
|
fallback: AINode;
|
|
@@ -241,7 +256,7 @@ declare module '@gammatech/aijsx' {
|
|
|
241
256
|
}
|
|
242
257
|
type ValidOpenAIVisionModel = 'gpt-4o' | 'gpt-4o-2024-05-13' | 'gpt-4-turbo-2024-04-09' | 'gpt-4-turbo' | 'gpt-4-vision-preview';
|
|
243
258
|
type ValidOpenAIChatModel = ValidOpenAIVisionModel | 'gpt-4' | 'gpt-4-0314' | 'gpt-4-0613' | 'gpt-4-32k' | 'gpt-4-32k-0314' | 'gpt-4-32k-0613' | 'gpt-4-1106-preview' | 'gpt-4-0125-preview' | 'gpt-3.5-turbo' | 'gpt-3.5-turbo-0301' | 'gpt-3.5-turbo-0613' | 'gpt-3.5-turbo-16k' | 'gpt-3.5-turbo-16k-0613' | 'gpt-3.5-turbo-1106' | 'gpt-3.5-turbo-0125';
|
|
244
|
-
declare const OpenAIClientContext: Context<
|
|
259
|
+
declare const OpenAIClientContext: Context<GetChatCompletionClientAndProvider<ValidOpenAIChatModel, OpenAI>>;
|
|
245
260
|
type OpenAIChatCompletionProps = {
|
|
246
261
|
model: ValidOpenAIChatModel;
|
|
247
262
|
maxTokens?: number;
|
|
@@ -265,8 +280,8 @@ declare module '@gammatech/aijsx' {
|
|
|
265
280
|
* The set of valid Claude models.
|
|
266
281
|
* @see https://docs.anthropic.com/claude/reference/selecting-a-model
|
|
267
282
|
*/
|
|
268
|
-
type ValidAnthropicChatModel = 'claude-instant-1.2' | 'claude-2.1' | 'claude-3-opus-20240229' | 'claude-3-sonnet-20240229' | 'claude-3-haiku-20240307';
|
|
269
|
-
declare const AnthropicClientContext: Context<
|
|
283
|
+
type ValidAnthropicChatModel = 'claude-instant-1.2' | 'claude-2.1' | 'claude-3-opus-20240229' | 'claude-3-sonnet-20240229' | 'claude-3-haiku-20240307' | 'claude-3-5-sonnet-20240620';
|
|
284
|
+
declare const AnthropicClientContext: Context<GetChatCompletionClientAndProvider<ValidAnthropicChatModel, AnthropicClient>>;
|
|
270
285
|
type AnthropicChatCompletionProps = {
|
|
271
286
|
model: ValidAnthropicChatModel;
|
|
272
287
|
maxTokens?: number;
|
|
@@ -291,7 +306,7 @@ declare module '@gammatech/aijsx' {
|
|
|
291
306
|
}
|
|
292
307
|
}
|
|
293
308
|
type ValidGoogleChatModel = 'gemini-1.5-pro' | 'gemini-1.5-flash';
|
|
294
|
-
declare const GoogleClientContext: Context<
|
|
309
|
+
declare const GoogleClientContext: Context<GetChatCompletionClientAndProvider<ValidGoogleChatModel, VertexAI>>;
|
|
295
310
|
type GoogleChatCompletionProps = {
|
|
296
311
|
model: ValidGoogleChatModel;
|
|
297
312
|
maxTokens?: number;
|
|
@@ -306,4 +321,4 @@ type GoogleChatCompletionProps = {
|
|
|
306
321
|
};
|
|
307
322
|
declare function GoogleChatCompletion(props: GoogleChatCompletionProps, ctx: RenderContext): JSX.Element;
|
|
308
323
|
|
|
309
|
-
export { AIComponent, AINode, AISpanAttributes, AISpanProcessor, AnthropicChatCompletion, type AnthropicChatCompletionRequest, AnthropicClientContext, AssistantMessage, type ChatCompletionClientAndProvider, ChatCompletionError, type ChatCompletionRequestPayloads, ChatMessage, Context, type CostFn, DebugMessage, DefaultMaxRetriesContext, EnrichingSpanProcessor, EvaluatorFn, EvaluatorResult, Fallback, GoogleChatCompletion, type GoogleChatCompletionRequest, GoogleClientContext, LogChatCompletionRequest, LogImplementation, OpenAIChatCompletion, type OpenAIChatCompletionRequest, type OpenAIChatMessage, OpenAIClientContext, ParseVariablesError, ProcessedAISpanAttributes, type Prompt, PromptInvalidOutputError, PromptParsed, ReadableSpan, RenderContext, Retry, RetryCountContext, SpanAttributes, SpanExporter, SpanProcessor, SystemMessage, type TokenizerFn, Trace, Tracer, UserMessage, type ValidAnthropicChatModel, type ValidGoogleChatModel, type ValidOpenAIChatModel, type ValidOpenAIVisionModel, anthropicTokenizer, computeUsage, createPrompt, createRenderContext, evaluatePrompt, isPromptParsed, openaiTokenizer, tracing };
|
|
324
|
+
export { AIComponent, AINode, AISpanAttributes, AISpanProcessor, AnthropicChatCompletion, type AnthropicChatCompletionRequest, AnthropicClientContext, AssistantMessage, type ChatCompletionClientAndProvider, ChatCompletionError, type ChatCompletionRequestPayloads, ChatMessage, Context, type CostFn, DebugMessage, DefaultMaxRetriesContext, EnrichingSpanProcessor, EvaluatorFn, EvaluatorResult, Fallback, type GetChatCompletionClientAndProvider, GoogleChatCompletion, type GoogleChatCompletionRequest, GoogleClientContext, LogChatCompletionRequest, LogImplementation, OpenAIChatCompletion, type OpenAIChatCompletionRequest, type OpenAIChatMessage, OpenAIClientContext, ParseVariablesError, ProcessedAISpanAttributes, type Prompt, PromptInvalidOutputError, PromptParsed, ReadableSpan, RenderContext, Retry, RetryCountContext, RetryLastErrorContext, SpanAttributes, SpanExporter, SpanProcessor, SystemMessage, type TokenizerFn, Trace, Tracer, UserMessage, type ValidAnthropicChatModel, type ValidGoogleChatModel, type ValidOpenAIChatModel, type ValidOpenAIVisionModel, anthropicTokenizer, computeUsage, createPrompt, createRenderContext, evaluatePrompt, isPromptParsed, openaiTokenizer, tracing };
|
package/dist/index.d.ts
CHANGED
|
@@ -13,8 +13,9 @@ declare class ChatCompletionError extends Error {
|
|
|
13
13
|
readonly chatCompletionRequest: LogChatCompletionRequest;
|
|
14
14
|
readonly status: number | undefined;
|
|
15
15
|
readonly shouldRetry: boolean;
|
|
16
|
+
readonly originalError?: Error | undefined;
|
|
16
17
|
readonly name = "ChatCompletionError";
|
|
17
|
-
constructor(message: string, chatCompletionRequest: LogChatCompletionRequest, status: number | undefined, shouldRetry?: boolean);
|
|
18
|
+
constructor(message: string, chatCompletionRequest: LogChatCompletionRequest, status: number | undefined, shouldRetry?: boolean, originalError?: Error | undefined);
|
|
18
19
|
}
|
|
19
20
|
|
|
20
21
|
declare const SystemMessage: (props: {
|
|
@@ -43,6 +44,10 @@ type ChatCompletionClientAndProvider<K> = {
|
|
|
43
44
|
completion: number;
|
|
44
45
|
}) => number;
|
|
45
46
|
};
|
|
47
|
+
type GetChatCompletionClientAndProvider<Model, Client> = (model: Model, args: {
|
|
48
|
+
retryCount: number;
|
|
49
|
+
lastError?: Error | null;
|
|
50
|
+
}) => Promise<ChatCompletionClientAndProvider<Client>>;
|
|
46
51
|
|
|
47
52
|
type CreateRenderContextOptions = {
|
|
48
53
|
logger?: LogImplementation;
|
|
@@ -52,15 +57,25 @@ type CreateRenderContextOptions = {
|
|
|
52
57
|
};
|
|
53
58
|
declare function createRenderContext({ logger, traceId, processor, contextValues, }?: CreateRenderContextOptions): RenderContext;
|
|
54
59
|
|
|
55
|
-
|
|
60
|
+
type ExcludeNumber<E extends number, T = number> = T extends E ? never : T;
|
|
61
|
+
type RetryCountContextValue = {
|
|
62
|
+
retryCount: 0;
|
|
63
|
+
lastError: null;
|
|
64
|
+
} | {
|
|
65
|
+
retryCount: ExcludeNumber<0>;
|
|
66
|
+
lastError: Error;
|
|
67
|
+
};
|
|
68
|
+
declare const RetryCountContext: Context<RetryCountContextValue>;
|
|
69
|
+
declare const RetryLastErrorContext: Context<Error | null>;
|
|
56
70
|
declare const DefaultMaxRetriesContext: Context<number>;
|
|
57
71
|
type RetryProps = {
|
|
58
72
|
shouldRetry: (error: Error) => boolean;
|
|
59
73
|
retries?: number;
|
|
74
|
+
lastError?: Error;
|
|
60
75
|
maxRetries?: number;
|
|
61
76
|
children: AINode;
|
|
62
77
|
};
|
|
63
|
-
declare function Retry({ shouldRetry, retries, maxRetries, children }: RetryProps, ctx: RenderContext): AsyncGenerator<string, void, unknown>;
|
|
78
|
+
declare function Retry({ shouldRetry, retries, maxRetries, lastError, children }: RetryProps, ctx: RenderContext): AsyncGenerator<string, void, unknown>;
|
|
64
79
|
|
|
65
80
|
type FallbackProps = {
|
|
66
81
|
fallback: AINode;
|
|
@@ -241,7 +256,7 @@ declare module '@gammatech/aijsx' {
|
|
|
241
256
|
}
|
|
242
257
|
type ValidOpenAIVisionModel = 'gpt-4o' | 'gpt-4o-2024-05-13' | 'gpt-4-turbo-2024-04-09' | 'gpt-4-turbo' | 'gpt-4-vision-preview';
|
|
243
258
|
type ValidOpenAIChatModel = ValidOpenAIVisionModel | 'gpt-4' | 'gpt-4-0314' | 'gpt-4-0613' | 'gpt-4-32k' | 'gpt-4-32k-0314' | 'gpt-4-32k-0613' | 'gpt-4-1106-preview' | 'gpt-4-0125-preview' | 'gpt-3.5-turbo' | 'gpt-3.5-turbo-0301' | 'gpt-3.5-turbo-0613' | 'gpt-3.5-turbo-16k' | 'gpt-3.5-turbo-16k-0613' | 'gpt-3.5-turbo-1106' | 'gpt-3.5-turbo-0125';
|
|
244
|
-
declare const OpenAIClientContext: Context<
|
|
259
|
+
declare const OpenAIClientContext: Context<GetChatCompletionClientAndProvider<ValidOpenAIChatModel, OpenAI>>;
|
|
245
260
|
type OpenAIChatCompletionProps = {
|
|
246
261
|
model: ValidOpenAIChatModel;
|
|
247
262
|
maxTokens?: number;
|
|
@@ -265,8 +280,8 @@ declare module '@gammatech/aijsx' {
|
|
|
265
280
|
* The set of valid Claude models.
|
|
266
281
|
* @see https://docs.anthropic.com/claude/reference/selecting-a-model
|
|
267
282
|
*/
|
|
268
|
-
type ValidAnthropicChatModel = 'claude-instant-1.2' | 'claude-2.1' | 'claude-3-opus-20240229' | 'claude-3-sonnet-20240229' | 'claude-3-haiku-20240307';
|
|
269
|
-
declare const AnthropicClientContext: Context<
|
|
283
|
+
type ValidAnthropicChatModel = 'claude-instant-1.2' | 'claude-2.1' | 'claude-3-opus-20240229' | 'claude-3-sonnet-20240229' | 'claude-3-haiku-20240307' | 'claude-3-5-sonnet-20240620';
|
|
284
|
+
declare const AnthropicClientContext: Context<GetChatCompletionClientAndProvider<ValidAnthropicChatModel, AnthropicClient>>;
|
|
270
285
|
type AnthropicChatCompletionProps = {
|
|
271
286
|
model: ValidAnthropicChatModel;
|
|
272
287
|
maxTokens?: number;
|
|
@@ -291,7 +306,7 @@ declare module '@gammatech/aijsx' {
|
|
|
291
306
|
}
|
|
292
307
|
}
|
|
293
308
|
type ValidGoogleChatModel = 'gemini-1.5-pro' | 'gemini-1.5-flash';
|
|
294
|
-
declare const GoogleClientContext: Context<
|
|
309
|
+
declare const GoogleClientContext: Context<GetChatCompletionClientAndProvider<ValidGoogleChatModel, VertexAI>>;
|
|
295
310
|
type GoogleChatCompletionProps = {
|
|
296
311
|
model: ValidGoogleChatModel;
|
|
297
312
|
maxTokens?: number;
|
|
@@ -306,4 +321,4 @@ type GoogleChatCompletionProps = {
|
|
|
306
321
|
};
|
|
307
322
|
declare function GoogleChatCompletion(props: GoogleChatCompletionProps, ctx: RenderContext): JSX.Element;
|
|
308
323
|
|
|
309
|
-
export { AIComponent, AINode, AISpanAttributes, AISpanProcessor, AnthropicChatCompletion, type AnthropicChatCompletionRequest, AnthropicClientContext, AssistantMessage, type ChatCompletionClientAndProvider, ChatCompletionError, type ChatCompletionRequestPayloads, ChatMessage, Context, type CostFn, DebugMessage, DefaultMaxRetriesContext, EnrichingSpanProcessor, EvaluatorFn, EvaluatorResult, Fallback, GoogleChatCompletion, type GoogleChatCompletionRequest, GoogleClientContext, LogChatCompletionRequest, LogImplementation, OpenAIChatCompletion, type OpenAIChatCompletionRequest, type OpenAIChatMessage, OpenAIClientContext, ParseVariablesError, ProcessedAISpanAttributes, type Prompt, PromptInvalidOutputError, PromptParsed, ReadableSpan, RenderContext, Retry, RetryCountContext, SpanAttributes, SpanExporter, SpanProcessor, SystemMessage, type TokenizerFn, Trace, Tracer, UserMessage, type ValidAnthropicChatModel, type ValidGoogleChatModel, type ValidOpenAIChatModel, type ValidOpenAIVisionModel, anthropicTokenizer, computeUsage, createPrompt, createRenderContext, evaluatePrompt, isPromptParsed, openaiTokenizer, tracing };
|
|
324
|
+
export { AIComponent, AINode, AISpanAttributes, AISpanProcessor, AnthropicChatCompletion, type AnthropicChatCompletionRequest, AnthropicClientContext, AssistantMessage, type ChatCompletionClientAndProvider, ChatCompletionError, type ChatCompletionRequestPayloads, ChatMessage, Context, type CostFn, DebugMessage, DefaultMaxRetriesContext, EnrichingSpanProcessor, EvaluatorFn, EvaluatorResult, Fallback, type GetChatCompletionClientAndProvider, GoogleChatCompletion, type GoogleChatCompletionRequest, GoogleClientContext, LogChatCompletionRequest, LogImplementation, OpenAIChatCompletion, type OpenAIChatCompletionRequest, type OpenAIChatMessage, OpenAIClientContext, ParseVariablesError, ProcessedAISpanAttributes, type Prompt, PromptInvalidOutputError, PromptParsed, ReadableSpan, RenderContext, Retry, RetryCountContext, RetryLastErrorContext, SpanAttributes, SpanExporter, SpanProcessor, SystemMessage, type TokenizerFn, Trace, Tracer, UserMessage, type ValidAnthropicChatModel, type ValidGoogleChatModel, type ValidOpenAIChatModel, type ValidOpenAIVisionModel, anthropicTokenizer, computeUsage, createPrompt, createRenderContext, evaluatePrompt, isPromptParsed, openaiTokenizer, tracing };
|
package/dist/index.js
CHANGED
|
@@ -56,6 +56,7 @@ __export(src_exports, {
|
|
|
56
56
|
PromptInvalidOutputError: () => PromptInvalidOutputError,
|
|
57
57
|
Retry: () => Retry,
|
|
58
58
|
RetryCountContext: () => RetryCountContext,
|
|
59
|
+
RetryLastErrorContext: () => RetryLastErrorContext,
|
|
59
60
|
SystemMessage: () => SystemMessage,
|
|
60
61
|
Trace: () => Trace,
|
|
61
62
|
UserMessage: () => UserMessage,
|
|
@@ -77,11 +78,12 @@ module.exports = __toCommonJS(src_exports);
|
|
|
77
78
|
|
|
78
79
|
// src/chat/errors.ts
|
|
79
80
|
var ChatCompletionError = class extends Error {
|
|
80
|
-
constructor(message, chatCompletionRequest, status, shouldRetry4 = false) {
|
|
81
|
+
constructor(message, chatCompletionRequest, status, shouldRetry4 = false, originalError) {
|
|
81
82
|
super(message);
|
|
82
83
|
this.chatCompletionRequest = chatCompletionRequest;
|
|
83
84
|
this.status = status;
|
|
84
85
|
this.shouldRetry = shouldRetry4;
|
|
86
|
+
this.originalError = originalError;
|
|
85
87
|
}
|
|
86
88
|
name = "ChatCompletionError";
|
|
87
89
|
};
|
|
@@ -1537,27 +1539,67 @@ function renderCloseTag(element) {
|
|
|
1537
1539
|
return `</${element.tag.name}>`;
|
|
1538
1540
|
}
|
|
1539
1541
|
|
|
1542
|
+
// src/utils.ts
|
|
1543
|
+
function getEnvVar(name, shouldThrow = true) {
|
|
1544
|
+
let env = globalThis.process?.env ?? void 0;
|
|
1545
|
+
if (env === void 0) {
|
|
1546
|
+
try {
|
|
1547
|
+
env = process.env;
|
|
1548
|
+
} catch {
|
|
1549
|
+
}
|
|
1550
|
+
}
|
|
1551
|
+
const result = env?.[name];
|
|
1552
|
+
if (result === void 0 && shouldThrow) {
|
|
1553
|
+
throw new Error(`Please specify env var '${name}'`);
|
|
1554
|
+
}
|
|
1555
|
+
return result;
|
|
1556
|
+
}
|
|
1557
|
+
var castToError = (e) => {
|
|
1558
|
+
if (e instanceof Error) {
|
|
1559
|
+
return e;
|
|
1560
|
+
}
|
|
1561
|
+
if (typeof e === "string") {
|
|
1562
|
+
return new Error(e);
|
|
1563
|
+
}
|
|
1564
|
+
return new Error("Unknown error");
|
|
1565
|
+
};
|
|
1566
|
+
|
|
1540
1567
|
// src/retry.tsx
|
|
1541
|
-
var RetryCountContext = createContext(
|
|
1568
|
+
var RetryCountContext = createContext({
|
|
1569
|
+
retryCount: 0,
|
|
1570
|
+
lastError: null
|
|
1571
|
+
});
|
|
1572
|
+
var RetryLastErrorContext = createContext(null);
|
|
1542
1573
|
var DefaultMaxRetriesContext = createContext(0);
|
|
1543
|
-
async function* Retry({ shouldRetry: shouldRetry4, retries = 0, maxRetries = 3, children }, ctx) {
|
|
1574
|
+
async function* Retry({ shouldRetry: shouldRetry4, retries = 0, maxRetries = 3, lastError, children }, ctx) {
|
|
1544
1575
|
const { render } = ctx;
|
|
1545
1576
|
let hasYieldedData = false;
|
|
1546
1577
|
try {
|
|
1578
|
+
const ctxValue = retries === 0 ? { retryCount: 0, lastError: null } : {
|
|
1579
|
+
retryCount: retries,
|
|
1580
|
+
lastError
|
|
1581
|
+
};
|
|
1547
1582
|
const result = render(
|
|
1548
|
-
/* @__PURE__ */ jsx(RetryCountContext.Provider, { value:
|
|
1583
|
+
/* @__PURE__ */ jsx(RetryCountContext.Provider, { value: ctxValue, children })
|
|
1549
1584
|
);
|
|
1550
1585
|
for await (const value of result) {
|
|
1551
1586
|
hasYieldedData = true;
|
|
1552
1587
|
yield value;
|
|
1553
1588
|
}
|
|
1554
1589
|
} catch (e) {
|
|
1555
|
-
|
|
1590
|
+
const err = castToError(e);
|
|
1591
|
+
if (hasYieldedData || retries >= maxRetries || !shouldRetry4(err)) {
|
|
1556
1592
|
throw e;
|
|
1557
1593
|
}
|
|
1558
1594
|
await backoff(retries);
|
|
1559
1595
|
yield* Retry(
|
|
1560
|
-
{
|
|
1596
|
+
{
|
|
1597
|
+
shouldRetry: shouldRetry4,
|
|
1598
|
+
retries: retries + 1,
|
|
1599
|
+
maxRetries,
|
|
1600
|
+
lastError: err,
|
|
1601
|
+
children
|
|
1602
|
+
},
|
|
1561
1603
|
ctx
|
|
1562
1604
|
);
|
|
1563
1605
|
}
|
|
@@ -1903,25 +1945,6 @@ function isPromptParsed2(prompt) {
|
|
|
1903
1945
|
// src/lib/openai/OpenAI.tsx
|
|
1904
1946
|
var import_openai2 = require("openai");
|
|
1905
1947
|
|
|
1906
|
-
// src/lib/openai/shouldRetryOpenAI.ts
|
|
1907
|
-
var import_openai = require("openai");
|
|
1908
|
-
var shouldRetryOpenAI = (error) => {
|
|
1909
|
-
if (error instanceof import_openai.OpenAI.APIConnectionError) {
|
|
1910
|
-
return true;
|
|
1911
|
-
}
|
|
1912
|
-
if (error instanceof import_openai.OpenAI.APIError) {
|
|
1913
|
-
if ("status" in error && typeof error.status === "number") {
|
|
1914
|
-
if (error.status === 409)
|
|
1915
|
-
return true;
|
|
1916
|
-
if (error.status === 429)
|
|
1917
|
-
return true;
|
|
1918
|
-
if (error.status >= 500)
|
|
1919
|
-
return true;
|
|
1920
|
-
}
|
|
1921
|
-
}
|
|
1922
|
-
return false;
|
|
1923
|
-
};
|
|
1924
|
-
|
|
1925
1948
|
// src/lib/openai/tokenizer.ts
|
|
1926
1949
|
var import_js_tiktoken = require("js-tiktoken");
|
|
1927
1950
|
var cl100kTokenizer = (0, import_js_tiktoken.getEncoding)("cl100k_base");
|
|
@@ -2033,25 +2056,39 @@ async function buildChatMessages(ctx, children, opts) {
|
|
|
2033
2056
|
});
|
|
2034
2057
|
}
|
|
2035
2058
|
|
|
2036
|
-
// src/
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
if (
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2059
|
+
// src/lib/openai/errors.ts
|
|
2060
|
+
var import_openai = require("openai");
|
|
2061
|
+
var extractStatusFromError = (error) => {
|
|
2062
|
+
if (error instanceof import_openai.OpenAI.APIError) {
|
|
2063
|
+
return error.status;
|
|
2064
|
+
} else if (error instanceof import_openai.OpenAI.APIConnectionError) {
|
|
2065
|
+
return void 0;
|
|
2066
|
+
} else {
|
|
2067
|
+
return void 0;
|
|
2044
2068
|
}
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2069
|
+
};
|
|
2070
|
+
var errorToChatCompletionError = (error, requestData) => {
|
|
2071
|
+
const castError = castToError(error);
|
|
2072
|
+
const status = extractStatusFromError(castError);
|
|
2073
|
+
let messagePrefix = "";
|
|
2074
|
+
if (error instanceof import_openai.OpenAI.APIError) {
|
|
2075
|
+
messagePrefix = "OpenAIClient.APIError: ";
|
|
2076
|
+
} else if (error instanceof import_openai.OpenAI.APIConnectionError) {
|
|
2077
|
+
messagePrefix = "OpenAIClient.APIConnectionError: ";
|
|
2048
2078
|
}
|
|
2049
|
-
|
|
2050
|
-
|
|
2079
|
+
const shouldRetry4 = status !== 400;
|
|
2080
|
+
return new ChatCompletionError(
|
|
2081
|
+
`${messagePrefix}${castError.message}`,
|
|
2082
|
+
requestData,
|
|
2083
|
+
status,
|
|
2084
|
+
shouldRetry4,
|
|
2085
|
+
error instanceof Error ? error : void 0
|
|
2086
|
+
);
|
|
2087
|
+
};
|
|
2051
2088
|
|
|
2052
2089
|
// src/lib/openai/OpenAI.tsx
|
|
2053
2090
|
var defaultClient = null;
|
|
2054
|
-
var OpenAIClientContext = createContext(() => {
|
|
2091
|
+
var OpenAIClientContext = createContext(async () => {
|
|
2055
2092
|
if (defaultClient) {
|
|
2056
2093
|
return defaultClient;
|
|
2057
2094
|
}
|
|
@@ -2123,9 +2160,16 @@ function OpenAIChatCompletion(props, ctx) {
|
|
|
2123
2160
|
async function* OpenAIChatCompletionInner(props, ctx) {
|
|
2124
2161
|
const startTime = performance.now();
|
|
2125
2162
|
const { logger, tracer, getContext } = ctx;
|
|
2126
|
-
const retryCount = getContext(RetryCountContext);
|
|
2163
|
+
const { retryCount, lastError } = getContext(RetryCountContext);
|
|
2127
2164
|
const span = tracer.getActiveSpan();
|
|
2128
|
-
const
|
|
2165
|
+
const getClientFn = getContext(OpenAIClientContext);
|
|
2166
|
+
const { client, provider, providerRegion, costFn } = await getClientFn(
|
|
2167
|
+
props.model,
|
|
2168
|
+
{
|
|
2169
|
+
retryCount,
|
|
2170
|
+
lastError
|
|
2171
|
+
}
|
|
2172
|
+
);
|
|
2129
2173
|
if (!client) {
|
|
2130
2174
|
throw new Error("[OpenAI] must supply OpenAI model via context");
|
|
2131
2175
|
}
|
|
@@ -2170,38 +2214,32 @@ async function* OpenAIChatCompletionInner(props, ctx) {
|
|
|
2170
2214
|
try {
|
|
2171
2215
|
chatResponse = await client.chat.completions.create(chatCompletionRequest);
|
|
2172
2216
|
} catch (ex) {
|
|
2173
|
-
|
|
2174
|
-
if (ex instanceof import_openai2.OpenAI.APIError) {
|
|
2175
|
-
throw new ChatCompletionError(
|
|
2176
|
-
`OpenAIClient.APIError: ${ex.message}`,
|
|
2177
|
-
logRequestData,
|
|
2178
|
-
ex.status,
|
|
2179
|
-
retry
|
|
2180
|
-
);
|
|
2181
|
-
} else if (ex instanceof Error) {
|
|
2182
|
-
throw new ChatCompletionError(
|
|
2183
|
-
ex.message,
|
|
2184
|
-
logRequestData,
|
|
2185
|
-
void 0,
|
|
2186
|
-
retry
|
|
2187
|
-
);
|
|
2188
|
-
}
|
|
2189
|
-
throw ex;
|
|
2217
|
+
throw errorToChatCompletionError(ex, logRequestData);
|
|
2190
2218
|
}
|
|
2191
2219
|
let finishReason = void 0;
|
|
2192
2220
|
let content = "";
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2221
|
+
try {
|
|
2222
|
+
for await (const message of chatResponse) {
|
|
2223
|
+
if (!message.choices || !message.choices[0]) {
|
|
2224
|
+
continue;
|
|
2225
|
+
}
|
|
2226
|
+
const delta = message.choices[0].delta;
|
|
2227
|
+
if (message.choices[0].finish_reason) {
|
|
2228
|
+
finishReason = message.choices[0].finish_reason;
|
|
2229
|
+
span.setAttributes({
|
|
2230
|
+
finishReason
|
|
2231
|
+
});
|
|
2232
|
+
}
|
|
2233
|
+
if (delta.content) {
|
|
2234
|
+
content += delta.content;
|
|
2235
|
+
yield delta.content;
|
|
2236
|
+
}
|
|
2204
2237
|
}
|
|
2238
|
+
} catch (e) {
|
|
2239
|
+
span.setAttributes({
|
|
2240
|
+
output: content
|
|
2241
|
+
});
|
|
2242
|
+
throw errorToChatCompletionError(e, logRequestData);
|
|
2205
2243
|
}
|
|
2206
2244
|
const outputMessage = {
|
|
2207
2245
|
role: "assistant",
|
|
@@ -2295,7 +2333,7 @@ var anthropicTokenizer = (message) => {
|
|
|
2295
2333
|
|
|
2296
2334
|
// src/lib/anthropic/Anthropic.tsx
|
|
2297
2335
|
var defaultClient2 = null;
|
|
2298
|
-
var AnthropicClientContext = createContext(() => {
|
|
2336
|
+
var AnthropicClientContext = createContext(async () => {
|
|
2299
2337
|
if (defaultClient2) {
|
|
2300
2338
|
return defaultClient2;
|
|
2301
2339
|
}
|
|
@@ -2374,7 +2412,7 @@ var shouldRetry2 = (error) => {
|
|
|
2374
2412
|
var shouldRetryFromStatus = (status) => Boolean(status && [424, 429, 500].includes(status));
|
|
2375
2413
|
var RE_INTERNAL_SERVER_MESSASGE = /The system encountered an unexpected error during processing/i;
|
|
2376
2414
|
var RE_RATE_LIMIT_MESSAGE = /Too many requests, please wait before trying again/;
|
|
2377
|
-
var
|
|
2415
|
+
var extractStatusFromError2 = (error) => {
|
|
2378
2416
|
if (typeof error !== "object" || !(error instanceof Error)) {
|
|
2379
2417
|
return;
|
|
2380
2418
|
}
|
|
@@ -2413,11 +2451,16 @@ function AnthropicChatCompletion(props, ctx) {
|
|
|
2413
2451
|
async function* AnthropicChatCompletionInner(props, ctx) {
|
|
2414
2452
|
const startTime = performance.now();
|
|
2415
2453
|
const { logger, tracer, getContext } = ctx;
|
|
2416
|
-
const retryCount = getContext(RetryCountContext);
|
|
2454
|
+
const { retryCount, lastError } = getContext(RetryCountContext);
|
|
2417
2455
|
const span = tracer.getActiveSpan();
|
|
2418
|
-
const
|
|
2419
|
-
|
|
2420
|
-
|
|
2456
|
+
const getClientFn = getContext(AnthropicClientContext);
|
|
2457
|
+
const { client, provider, providerRegion, costFn } = await getClientFn(
|
|
2458
|
+
props.model,
|
|
2459
|
+
{
|
|
2460
|
+
retryCount,
|
|
2461
|
+
lastError
|
|
2462
|
+
}
|
|
2463
|
+
);
|
|
2421
2464
|
if (!client) {
|
|
2422
2465
|
throw new Error(
|
|
2423
2466
|
"[AnthropicChatCompletion] must supply AnthropicClient via context"
|
|
@@ -2468,7 +2511,7 @@ async function* AnthropicChatCompletionInner(props, ctx) {
|
|
|
2468
2511
|
response = client.messages.stream(anthropicCompletionRequest);
|
|
2469
2512
|
} catch (err) {
|
|
2470
2513
|
if (err instanceof import_sdk.default.APIError) {
|
|
2471
|
-
const status =
|
|
2514
|
+
const status = extractStatusFromError2(err);
|
|
2472
2515
|
const retry = shouldRetryFromStatus(status);
|
|
2473
2516
|
throw new ChatCompletionError(
|
|
2474
2517
|
`AnthropicClient.APIError: ${err.message}`,
|
|
@@ -2477,7 +2520,7 @@ async function* AnthropicChatCompletionInner(props, ctx) {
|
|
|
2477
2520
|
retry
|
|
2478
2521
|
);
|
|
2479
2522
|
} else if (err instanceof Error) {
|
|
2480
|
-
const status =
|
|
2523
|
+
const status = extractStatusFromError2(err);
|
|
2481
2524
|
const retry = shouldRetryFromStatus(status);
|
|
2482
2525
|
throw new ChatCompletionError(err.message, logRequestData, status, retry);
|
|
2483
2526
|
}
|
|
@@ -2500,10 +2543,16 @@ async function* AnthropicChatCompletionInner(props, ctx) {
|
|
|
2500
2543
|
if (event.type === "message_delta") {
|
|
2501
2544
|
finishReason = event.delta.stop_reason;
|
|
2502
2545
|
outputUsage = event.usage?.output_tokens;
|
|
2546
|
+
span.setAttributes({
|
|
2547
|
+
finishReason
|
|
2548
|
+
});
|
|
2503
2549
|
}
|
|
2504
2550
|
}
|
|
2505
2551
|
} catch (e) {
|
|
2506
|
-
|
|
2552
|
+
span.setAttributes({
|
|
2553
|
+
output: content
|
|
2554
|
+
});
|
|
2555
|
+
const status = extractStatusFromError2(e);
|
|
2507
2556
|
const retry = shouldRetryFromStatus(status);
|
|
2508
2557
|
throw new ChatCompletionError(e.message, logRequestData, status, retry);
|
|
2509
2558
|
}
|
|
@@ -2590,14 +2639,15 @@ var extractStatusFromMessage = (message) => {
|
|
|
2590
2639
|
}
|
|
2591
2640
|
return 500;
|
|
2592
2641
|
};
|
|
2593
|
-
var
|
|
2642
|
+
var errorToChatCompletionError2 = (error, requestData) => {
|
|
2594
2643
|
const status = extractStatusFromMessage(error.message);
|
|
2595
2644
|
const shouldRetry4 = status !== 400;
|
|
2596
2645
|
return new ChatCompletionError(
|
|
2597
2646
|
error.message,
|
|
2598
2647
|
requestData,
|
|
2599
2648
|
status,
|
|
2600
|
-
shouldRetry4
|
|
2649
|
+
shouldRetry4,
|
|
2650
|
+
error
|
|
2601
2651
|
);
|
|
2602
2652
|
};
|
|
2603
2653
|
|
|
@@ -2624,7 +2674,7 @@ var DEFAULT_SAFETY_SETTINGS = [
|
|
|
2624
2674
|
threshold: import_vertexai.HarmBlockThreshold.BLOCK_ONLY_HIGH
|
|
2625
2675
|
}
|
|
2626
2676
|
];
|
|
2627
|
-
var GoogleClientContext = createContext(() => {
|
|
2677
|
+
var GoogleClientContext = createContext(async () => {
|
|
2628
2678
|
if (defaultClient3) {
|
|
2629
2679
|
return defaultClient3;
|
|
2630
2680
|
}
|
|
@@ -2705,9 +2755,16 @@ function GoogleChatCompletion(props, ctx) {
|
|
|
2705
2755
|
async function* GoogleChatCompletionInner(props, ctx) {
|
|
2706
2756
|
const startTime = performance.now();
|
|
2707
2757
|
const { logger, tracer, getContext } = ctx;
|
|
2708
|
-
const retryCount = getContext(RetryCountContext);
|
|
2758
|
+
const { retryCount, lastError } = getContext(RetryCountContext);
|
|
2709
2759
|
const span = tracer.getActiveSpan();
|
|
2710
|
-
const
|
|
2760
|
+
const getClientFn = getContext(GoogleClientContext);
|
|
2761
|
+
const { client, provider, providerRegion, costFn } = await getClientFn(
|
|
2762
|
+
props.model,
|
|
2763
|
+
{
|
|
2764
|
+
retryCount,
|
|
2765
|
+
lastError
|
|
2766
|
+
}
|
|
2767
|
+
);
|
|
2711
2768
|
if (!client) {
|
|
2712
2769
|
throw new Error(
|
|
2713
2770
|
"[GoogleChatCompletion] must supply GoogleClient via context"
|
|
@@ -2762,7 +2819,7 @@ async function* GoogleChatCompletionInner(props, ctx) {
|
|
|
2762
2819
|
try {
|
|
2763
2820
|
response = await model.generateContentStream(googleCompletionRequest);
|
|
2764
2821
|
} catch (err) {
|
|
2765
|
-
throw
|
|
2822
|
+
throw errorToChatCompletionError2(err, logRequestData);
|
|
2766
2823
|
}
|
|
2767
2824
|
let content = "";
|
|
2768
2825
|
let outputUsage = 0;
|
|
@@ -2773,6 +2830,9 @@ async function* GoogleChatCompletionInner(props, ctx) {
|
|
|
2773
2830
|
if (event.candidates) {
|
|
2774
2831
|
if (event.candidates[0]?.finishReason) {
|
|
2775
2832
|
finishReason = event.candidates[0].finishReason;
|
|
2833
|
+
span.setAttributes({
|
|
2834
|
+
finishReason
|
|
2835
|
+
});
|
|
2776
2836
|
}
|
|
2777
2837
|
if (event.usageMetadata) {
|
|
2778
2838
|
if (event.usageMetadata.promptTokenCount) {
|
|
@@ -2808,7 +2868,10 @@ async function* GoogleChatCompletionInner(props, ctx) {
|
|
|
2808
2868
|
}
|
|
2809
2869
|
}
|
|
2810
2870
|
} catch (err) {
|
|
2811
|
-
|
|
2871
|
+
span.setAttributes({
|
|
2872
|
+
output: content
|
|
2873
|
+
});
|
|
2874
|
+
throw errorToChatCompletionError2(err, logRequestData);
|
|
2812
2875
|
}
|
|
2813
2876
|
const outputMessage = {
|
|
2814
2877
|
role: "assistant",
|
|
@@ -2832,8 +2895,7 @@ async function* GoogleChatCompletionInner(props, ctx) {
|
|
|
2832
2895
|
span.setAttributes({
|
|
2833
2896
|
tokensUsed,
|
|
2834
2897
|
output: content,
|
|
2835
|
-
cost
|
|
2836
|
-
finishReason
|
|
2898
|
+
cost
|
|
2837
2899
|
});
|
|
2838
2900
|
}
|
|
2839
2901
|
function cleanChatCompletionRequest3(chatCompletionRequest) {
|
|
@@ -2896,6 +2958,7 @@ var import_vertexai2 = require("@google-cloud/vertexai");
|
|
|
2896
2958
|
PromptInvalidOutputError,
|
|
2897
2959
|
Retry,
|
|
2898
2960
|
RetryCountContext,
|
|
2961
|
+
RetryLastErrorContext,
|
|
2899
2962
|
SystemMessage,
|
|
2900
2963
|
Trace,
|
|
2901
2964
|
UserMessage,
|
package/dist/index.mjs
CHANGED
|
@@ -8,11 +8,12 @@ import {
|
|
|
8
8
|
|
|
9
9
|
// src/chat/errors.ts
|
|
10
10
|
var ChatCompletionError = class extends Error {
|
|
11
|
-
constructor(message, chatCompletionRequest, status, shouldRetry4 = false) {
|
|
11
|
+
constructor(message, chatCompletionRequest, status, shouldRetry4 = false, originalError) {
|
|
12
12
|
super(message);
|
|
13
13
|
this.chatCompletionRequest = chatCompletionRequest;
|
|
14
14
|
this.status = status;
|
|
15
15
|
this.shouldRetry = shouldRetry4;
|
|
16
|
+
this.originalError = originalError;
|
|
16
17
|
}
|
|
17
18
|
name = "ChatCompletionError";
|
|
18
19
|
};
|
|
@@ -1435,27 +1436,67 @@ function renderCloseTag(element) {
|
|
|
1435
1436
|
return `</${element.tag.name}>`;
|
|
1436
1437
|
}
|
|
1437
1438
|
|
|
1439
|
+
// src/utils.ts
|
|
1440
|
+
function getEnvVar(name, shouldThrow = true) {
|
|
1441
|
+
let env = globalThis.process?.env ?? void 0;
|
|
1442
|
+
if (env === void 0) {
|
|
1443
|
+
try {
|
|
1444
|
+
env = process.env;
|
|
1445
|
+
} catch {
|
|
1446
|
+
}
|
|
1447
|
+
}
|
|
1448
|
+
const result = env?.[name];
|
|
1449
|
+
if (result === void 0 && shouldThrow) {
|
|
1450
|
+
throw new Error(`Please specify env var '${name}'`);
|
|
1451
|
+
}
|
|
1452
|
+
return result;
|
|
1453
|
+
}
|
|
1454
|
+
var castToError = (e) => {
|
|
1455
|
+
if (e instanceof Error) {
|
|
1456
|
+
return e;
|
|
1457
|
+
}
|
|
1458
|
+
if (typeof e === "string") {
|
|
1459
|
+
return new Error(e);
|
|
1460
|
+
}
|
|
1461
|
+
return new Error("Unknown error");
|
|
1462
|
+
};
|
|
1463
|
+
|
|
1438
1464
|
// src/retry.tsx
|
|
1439
|
-
var RetryCountContext = createContext(
|
|
1465
|
+
var RetryCountContext = createContext({
|
|
1466
|
+
retryCount: 0,
|
|
1467
|
+
lastError: null
|
|
1468
|
+
});
|
|
1469
|
+
var RetryLastErrorContext = createContext(null);
|
|
1440
1470
|
var DefaultMaxRetriesContext = createContext(0);
|
|
1441
|
-
async function* Retry({ shouldRetry: shouldRetry4, retries = 0, maxRetries = 3, children }, ctx) {
|
|
1471
|
+
async function* Retry({ shouldRetry: shouldRetry4, retries = 0, maxRetries = 3, lastError, children }, ctx) {
|
|
1442
1472
|
const { render } = ctx;
|
|
1443
1473
|
let hasYieldedData = false;
|
|
1444
1474
|
try {
|
|
1475
|
+
const ctxValue = retries === 0 ? { retryCount: 0, lastError: null } : {
|
|
1476
|
+
retryCount: retries,
|
|
1477
|
+
lastError
|
|
1478
|
+
};
|
|
1445
1479
|
const result = render(
|
|
1446
|
-
/* @__PURE__ */ jsx(RetryCountContext.Provider, { value:
|
|
1480
|
+
/* @__PURE__ */ jsx(RetryCountContext.Provider, { value: ctxValue, children })
|
|
1447
1481
|
);
|
|
1448
1482
|
for await (const value of result) {
|
|
1449
1483
|
hasYieldedData = true;
|
|
1450
1484
|
yield value;
|
|
1451
1485
|
}
|
|
1452
1486
|
} catch (e) {
|
|
1453
|
-
|
|
1487
|
+
const err = castToError(e);
|
|
1488
|
+
if (hasYieldedData || retries >= maxRetries || !shouldRetry4(err)) {
|
|
1454
1489
|
throw e;
|
|
1455
1490
|
}
|
|
1456
1491
|
await backoff(retries);
|
|
1457
1492
|
yield* Retry(
|
|
1458
|
-
{
|
|
1493
|
+
{
|
|
1494
|
+
shouldRetry: shouldRetry4,
|
|
1495
|
+
retries: retries + 1,
|
|
1496
|
+
maxRetries,
|
|
1497
|
+
lastError: err,
|
|
1498
|
+
children
|
|
1499
|
+
},
|
|
1459
1500
|
ctx
|
|
1460
1501
|
);
|
|
1461
1502
|
}
|
|
@@ -1801,25 +1842,6 @@ function isPromptParsed2(prompt) {
|
|
|
1801
1842
|
// src/lib/openai/OpenAI.tsx
|
|
1802
1843
|
import { OpenAI as OpenAIClient2 } from "openai";
|
|
1803
1844
|
|
|
1804
|
-
// src/lib/openai/shouldRetryOpenAI.ts
|
|
1805
|
-
import { OpenAI as OpenAIClient } from "openai";
|
|
1806
|
-
var shouldRetryOpenAI = (error) => {
|
|
1807
|
-
if (error instanceof OpenAIClient.APIConnectionError) {
|
|
1808
|
-
return true;
|
|
1809
|
-
}
|
|
1810
|
-
if (error instanceof OpenAIClient.APIError) {
|
|
1811
|
-
if ("status" in error && typeof error.status === "number") {
|
|
1812
|
-
if (error.status === 409)
|
|
1813
|
-
return true;
|
|
1814
|
-
if (error.status === 429)
|
|
1815
|
-
return true;
|
|
1816
|
-
if (error.status >= 500)
|
|
1817
|
-
return true;
|
|
1818
|
-
}
|
|
1819
|
-
}
|
|
1820
|
-
return false;
|
|
1821
|
-
};
|
|
1822
|
-
|
|
1823
1845
|
// src/lib/openai/tokenizer.ts
|
|
1824
1846
|
import { getEncoding } from "js-tiktoken";
|
|
1825
1847
|
var cl100kTokenizer = getEncoding("cl100k_base");
|
|
@@ -1931,25 +1953,39 @@ async function buildChatMessages(ctx, children, opts) {
|
|
|
1931
1953
|
});
|
|
1932
1954
|
}
|
|
1933
1955
|
|
|
1934
|
-
// src/
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
if (
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1956
|
+
// src/lib/openai/errors.ts
|
|
1957
|
+
import { OpenAI as OpenAIClient } from "openai";
|
|
1958
|
+
var extractStatusFromError = (error) => {
|
|
1959
|
+
if (error instanceof OpenAIClient.APIError) {
|
|
1960
|
+
return error.status;
|
|
1961
|
+
} else if (error instanceof OpenAIClient.APIConnectionError) {
|
|
1962
|
+
return void 0;
|
|
1963
|
+
} else {
|
|
1964
|
+
return void 0;
|
|
1942
1965
|
}
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1966
|
+
};
|
|
1967
|
+
var errorToChatCompletionError = (error, requestData) => {
|
|
1968
|
+
const castError = castToError(error);
|
|
1969
|
+
const status = extractStatusFromError(castError);
|
|
1970
|
+
let messagePrefix = "";
|
|
1971
|
+
if (error instanceof OpenAIClient.APIError) {
|
|
1972
|
+
messagePrefix = "OpenAIClient.APIError: ";
|
|
1973
|
+
} else if (error instanceof OpenAIClient.APIConnectionError) {
|
|
1974
|
+
messagePrefix = "OpenAIClient.APIConnectionError: ";
|
|
1946
1975
|
}
|
|
1947
|
-
|
|
1948
|
-
|
|
1976
|
+
const shouldRetry4 = status !== 400;
|
|
1977
|
+
return new ChatCompletionError(
|
|
1978
|
+
`${messagePrefix}${castError.message}`,
|
|
1979
|
+
requestData,
|
|
1980
|
+
status,
|
|
1981
|
+
shouldRetry4,
|
|
1982
|
+
error instanceof Error ? error : void 0
|
|
1983
|
+
);
|
|
1984
|
+
};
|
|
1949
1985
|
|
|
1950
1986
|
// src/lib/openai/OpenAI.tsx
|
|
1951
1987
|
var defaultClient = null;
|
|
1952
|
-
var OpenAIClientContext = createContext(() => {
|
|
1988
|
+
var OpenAIClientContext = createContext(async () => {
|
|
1953
1989
|
if (defaultClient) {
|
|
1954
1990
|
return defaultClient;
|
|
1955
1991
|
}
|
|
@@ -2021,9 +2057,16 @@ function OpenAIChatCompletion(props, ctx) {
|
|
|
2021
2057
|
async function* OpenAIChatCompletionInner(props, ctx) {
|
|
2022
2058
|
const startTime = performance.now();
|
|
2023
2059
|
const { logger, tracer, getContext } = ctx;
|
|
2024
|
-
const retryCount = getContext(RetryCountContext);
|
|
2060
|
+
const { retryCount, lastError } = getContext(RetryCountContext);
|
|
2025
2061
|
const span = tracer.getActiveSpan();
|
|
2026
|
-
const
|
|
2062
|
+
const getClientFn = getContext(OpenAIClientContext);
|
|
2063
|
+
const { client, provider, providerRegion, costFn } = await getClientFn(
|
|
2064
|
+
props.model,
|
|
2065
|
+
{
|
|
2066
|
+
retryCount,
|
|
2067
|
+
lastError
|
|
2068
|
+
}
|
|
2069
|
+
);
|
|
2027
2070
|
if (!client) {
|
|
2028
2071
|
throw new Error("[OpenAI] must supply OpenAI model via context");
|
|
2029
2072
|
}
|
|
@@ -2068,38 +2111,32 @@ async function* OpenAIChatCompletionInner(props, ctx) {
|
|
|
2068
2111
|
try {
|
|
2069
2112
|
chatResponse = await client.chat.completions.create(chatCompletionRequest);
|
|
2070
2113
|
} catch (ex) {
|
|
2071
|
-
|
|
2072
|
-
if (ex instanceof OpenAIClient2.APIError) {
|
|
2073
|
-
throw new ChatCompletionError(
|
|
2074
|
-
`OpenAIClient.APIError: ${ex.message}`,
|
|
2075
|
-
logRequestData,
|
|
2076
|
-
ex.status,
|
|
2077
|
-
retry
|
|
2078
|
-
);
|
|
2079
|
-
} else if (ex instanceof Error) {
|
|
2080
|
-
throw new ChatCompletionError(
|
|
2081
|
-
ex.message,
|
|
2082
|
-
logRequestData,
|
|
2083
|
-
void 0,
|
|
2084
|
-
retry
|
|
2085
|
-
);
|
|
2086
|
-
}
|
|
2087
|
-
throw ex;
|
|
2114
|
+
throw errorToChatCompletionError(ex, logRequestData);
|
|
2088
2115
|
}
|
|
2089
2116
|
let finishReason = void 0;
|
|
2090
2117
|
let content = "";
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2118
|
+
try {
|
|
2119
|
+
for await (const message of chatResponse) {
|
|
2120
|
+
if (!message.choices || !message.choices[0]) {
|
|
2121
|
+
continue;
|
|
2122
|
+
}
|
|
2123
|
+
const delta = message.choices[0].delta;
|
|
2124
|
+
if (message.choices[0].finish_reason) {
|
|
2125
|
+
finishReason = message.choices[0].finish_reason;
|
|
2126
|
+
span.setAttributes({
|
|
2127
|
+
finishReason
|
|
2128
|
+
});
|
|
2129
|
+
}
|
|
2130
|
+
if (delta.content) {
|
|
2131
|
+
content += delta.content;
|
|
2132
|
+
yield delta.content;
|
|
2133
|
+
}
|
|
2102
2134
|
}
|
|
2135
|
+
} catch (e) {
|
|
2136
|
+
span.setAttributes({
|
|
2137
|
+
output: content
|
|
2138
|
+
});
|
|
2139
|
+
throw errorToChatCompletionError(e, logRequestData);
|
|
2103
2140
|
}
|
|
2104
2141
|
const outputMessage = {
|
|
2105
2142
|
role: "assistant",
|
|
@@ -2193,7 +2230,7 @@ var anthropicTokenizer = (message) => {
|
|
|
2193
2230
|
|
|
2194
2231
|
// src/lib/anthropic/Anthropic.tsx
|
|
2195
2232
|
var defaultClient2 = null;
|
|
2196
|
-
var AnthropicClientContext = createContext(() => {
|
|
2233
|
+
var AnthropicClientContext = createContext(async () => {
|
|
2197
2234
|
if (defaultClient2) {
|
|
2198
2235
|
return defaultClient2;
|
|
2199
2236
|
}
|
|
@@ -2272,7 +2309,7 @@ var shouldRetry2 = (error) => {
|
|
|
2272
2309
|
var shouldRetryFromStatus = (status) => Boolean(status && [424, 429, 500].includes(status));
|
|
2273
2310
|
var RE_INTERNAL_SERVER_MESSASGE = /The system encountered an unexpected error during processing/i;
|
|
2274
2311
|
var RE_RATE_LIMIT_MESSAGE = /Too many requests, please wait before trying again/;
|
|
2275
|
-
var
|
|
2312
|
+
var extractStatusFromError2 = (error) => {
|
|
2276
2313
|
if (typeof error !== "object" || !(error instanceof Error)) {
|
|
2277
2314
|
return;
|
|
2278
2315
|
}
|
|
@@ -2311,11 +2348,16 @@ function AnthropicChatCompletion(props, ctx) {
|
|
|
2311
2348
|
async function* AnthropicChatCompletionInner(props, ctx) {
|
|
2312
2349
|
const startTime = performance.now();
|
|
2313
2350
|
const { logger, tracer, getContext } = ctx;
|
|
2314
|
-
const retryCount = getContext(RetryCountContext);
|
|
2351
|
+
const { retryCount, lastError } = getContext(RetryCountContext);
|
|
2315
2352
|
const span = tracer.getActiveSpan();
|
|
2316
|
-
const
|
|
2317
|
-
|
|
2318
|
-
|
|
2353
|
+
const getClientFn = getContext(AnthropicClientContext);
|
|
2354
|
+
const { client, provider, providerRegion, costFn } = await getClientFn(
|
|
2355
|
+
props.model,
|
|
2356
|
+
{
|
|
2357
|
+
retryCount,
|
|
2358
|
+
lastError
|
|
2359
|
+
}
|
|
2360
|
+
);
|
|
2319
2361
|
if (!client) {
|
|
2320
2362
|
throw new Error(
|
|
2321
2363
|
"[AnthropicChatCompletion] must supply AnthropicClient via context"
|
|
@@ -2366,7 +2408,7 @@ async function* AnthropicChatCompletionInner(props, ctx) {
|
|
|
2366
2408
|
response = client.messages.stream(anthropicCompletionRequest);
|
|
2367
2409
|
} catch (err) {
|
|
2368
2410
|
if (err instanceof AnthropicClient.APIError) {
|
|
2369
|
-
const status =
|
|
2411
|
+
const status = extractStatusFromError2(err);
|
|
2370
2412
|
const retry = shouldRetryFromStatus(status);
|
|
2371
2413
|
throw new ChatCompletionError(
|
|
2372
2414
|
`AnthropicClient.APIError: ${err.message}`,
|
|
@@ -2375,7 +2417,7 @@ async function* AnthropicChatCompletionInner(props, ctx) {
|
|
|
2375
2417
|
retry
|
|
2376
2418
|
);
|
|
2377
2419
|
} else if (err instanceof Error) {
|
|
2378
|
-
const status =
|
|
2420
|
+
const status = extractStatusFromError2(err);
|
|
2379
2421
|
const retry = shouldRetryFromStatus(status);
|
|
2380
2422
|
throw new ChatCompletionError(err.message, logRequestData, status, retry);
|
|
2381
2423
|
}
|
|
@@ -2398,10 +2440,16 @@ async function* AnthropicChatCompletionInner(props, ctx) {
|
|
|
2398
2440
|
if (event.type === "message_delta") {
|
|
2399
2441
|
finishReason = event.delta.stop_reason;
|
|
2400
2442
|
outputUsage = event.usage?.output_tokens;
|
|
2443
|
+
span.setAttributes({
|
|
2444
|
+
finishReason
|
|
2445
|
+
});
|
|
2401
2446
|
}
|
|
2402
2447
|
}
|
|
2403
2448
|
} catch (e) {
|
|
2404
|
-
|
|
2449
|
+
span.setAttributes({
|
|
2450
|
+
output: content
|
|
2451
|
+
});
|
|
2452
|
+
const status = extractStatusFromError2(e);
|
|
2405
2453
|
const retry = shouldRetryFromStatus(status);
|
|
2406
2454
|
throw new ChatCompletionError(e.message, logRequestData, status, retry);
|
|
2407
2455
|
}
|
|
@@ -2492,14 +2540,15 @@ var extractStatusFromMessage = (message) => {
|
|
|
2492
2540
|
}
|
|
2493
2541
|
return 500;
|
|
2494
2542
|
};
|
|
2495
|
-
var
|
|
2543
|
+
var errorToChatCompletionError2 = (error, requestData) => {
|
|
2496
2544
|
const status = extractStatusFromMessage(error.message);
|
|
2497
2545
|
const shouldRetry4 = status !== 400;
|
|
2498
2546
|
return new ChatCompletionError(
|
|
2499
2547
|
error.message,
|
|
2500
2548
|
requestData,
|
|
2501
2549
|
status,
|
|
2502
|
-
shouldRetry4
|
|
2550
|
+
shouldRetry4,
|
|
2551
|
+
error
|
|
2503
2552
|
);
|
|
2504
2553
|
};
|
|
2505
2554
|
|
|
@@ -2526,7 +2575,7 @@ var DEFAULT_SAFETY_SETTINGS = [
|
|
|
2526
2575
|
threshold: HarmBlockThreshold.BLOCK_ONLY_HIGH
|
|
2527
2576
|
}
|
|
2528
2577
|
];
|
|
2529
|
-
var GoogleClientContext = createContext(() => {
|
|
2578
|
+
var GoogleClientContext = createContext(async () => {
|
|
2530
2579
|
if (defaultClient3) {
|
|
2531
2580
|
return defaultClient3;
|
|
2532
2581
|
}
|
|
@@ -2607,9 +2656,16 @@ function GoogleChatCompletion(props, ctx) {
|
|
|
2607
2656
|
async function* GoogleChatCompletionInner(props, ctx) {
|
|
2608
2657
|
const startTime = performance.now();
|
|
2609
2658
|
const { logger, tracer, getContext } = ctx;
|
|
2610
|
-
const retryCount = getContext(RetryCountContext);
|
|
2659
|
+
const { retryCount, lastError } = getContext(RetryCountContext);
|
|
2611
2660
|
const span = tracer.getActiveSpan();
|
|
2612
|
-
const
|
|
2661
|
+
const getClientFn = getContext(GoogleClientContext);
|
|
2662
|
+
const { client, provider, providerRegion, costFn } = await getClientFn(
|
|
2663
|
+
props.model,
|
|
2664
|
+
{
|
|
2665
|
+
retryCount,
|
|
2666
|
+
lastError
|
|
2667
|
+
}
|
|
2668
|
+
);
|
|
2613
2669
|
if (!client) {
|
|
2614
2670
|
throw new Error(
|
|
2615
2671
|
"[GoogleChatCompletion] must supply GoogleClient via context"
|
|
@@ -2664,7 +2720,7 @@ async function* GoogleChatCompletionInner(props, ctx) {
|
|
|
2664
2720
|
try {
|
|
2665
2721
|
response = await model.generateContentStream(googleCompletionRequest);
|
|
2666
2722
|
} catch (err) {
|
|
2667
|
-
throw
|
|
2723
|
+
throw errorToChatCompletionError2(err, logRequestData);
|
|
2668
2724
|
}
|
|
2669
2725
|
let content = "";
|
|
2670
2726
|
let outputUsage = 0;
|
|
@@ -2675,6 +2731,9 @@ async function* GoogleChatCompletionInner(props, ctx) {
|
|
|
2675
2731
|
if (event.candidates) {
|
|
2676
2732
|
if (event.candidates[0]?.finishReason) {
|
|
2677
2733
|
finishReason = event.candidates[0].finishReason;
|
|
2734
|
+
span.setAttributes({
|
|
2735
|
+
finishReason
|
|
2736
|
+
});
|
|
2678
2737
|
}
|
|
2679
2738
|
if (event.usageMetadata) {
|
|
2680
2739
|
if (event.usageMetadata.promptTokenCount) {
|
|
@@ -2710,7 +2769,10 @@ async function* GoogleChatCompletionInner(props, ctx) {
|
|
|
2710
2769
|
}
|
|
2711
2770
|
}
|
|
2712
2771
|
} catch (err) {
|
|
2713
|
-
|
|
2772
|
+
span.setAttributes({
|
|
2773
|
+
output: content
|
|
2774
|
+
});
|
|
2775
|
+
throw errorToChatCompletionError2(err, logRequestData);
|
|
2714
2776
|
}
|
|
2715
2777
|
const outputMessage = {
|
|
2716
2778
|
role: "assistant",
|
|
@@ -2734,8 +2796,7 @@ async function* GoogleChatCompletionInner(props, ctx) {
|
|
|
2734
2796
|
span.setAttributes({
|
|
2735
2797
|
tokensUsed,
|
|
2736
2798
|
output: content,
|
|
2737
|
-
cost
|
|
2738
|
-
finishReason
|
|
2799
|
+
cost
|
|
2739
2800
|
});
|
|
2740
2801
|
}
|
|
2741
2802
|
function cleanChatCompletionRequest3(chatCompletionRequest) {
|
|
@@ -2801,6 +2862,7 @@ export {
|
|
|
2801
2862
|
PromptInvalidOutputError,
|
|
2802
2863
|
Retry,
|
|
2803
2864
|
RetryCountContext,
|
|
2865
|
+
RetryLastErrorContext,
|
|
2804
2866
|
SystemMessage,
|
|
2805
2867
|
Trace,
|
|
2806
2868
|
UserMessage,
|