@nuvin/nuvin-core 1.6.0 → 1.6.2
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/VERSION +2 -2
- package/dist/index.d.ts +43 -11
- package/dist/index.js +473 -167
- package/package.json +1 -1
package/dist/VERSION
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -540,7 +540,6 @@ type SendMessageOptions = {
|
|
|
540
540
|
conversationId?: string;
|
|
541
541
|
stream?: boolean;
|
|
542
542
|
signal?: AbortSignal;
|
|
543
|
-
retry?: boolean;
|
|
544
543
|
};
|
|
545
544
|
type UserAttachment = ImageContentPart & {
|
|
546
545
|
token?: string;
|
|
@@ -1994,6 +1993,38 @@ declare class GithubAuthTransport implements HttpTransport {
|
|
|
1994
1993
|
get(url: string, headers?: HttpHeaders, signal?: AbortSignal): Promise<TransportResponse>;
|
|
1995
1994
|
}
|
|
1996
1995
|
|
|
1996
|
+
interface RetryConfig {
|
|
1997
|
+
maxRetries: number;
|
|
1998
|
+
baseDelayMs: number;
|
|
1999
|
+
maxDelayMs: number;
|
|
2000
|
+
backoffMultiplier: number;
|
|
2001
|
+
jitterFactor: number;
|
|
2002
|
+
retryableStatusCodes: number[];
|
|
2003
|
+
onRetry?: (attempt: number, error: Error, delayMs: number) => void;
|
|
2004
|
+
onExhausted?: (error: Error, attempts: number) => void;
|
|
2005
|
+
}
|
|
2006
|
+
declare const DEFAULT_RETRY_CONFIG: RetryConfig;
|
|
2007
|
+
declare class AbortError extends Error {
|
|
2008
|
+
constructor(message?: string);
|
|
2009
|
+
}
|
|
2010
|
+
declare class RetryTransport implements HttpTransport {
|
|
2011
|
+
private inner;
|
|
2012
|
+
private config;
|
|
2013
|
+
constructor(inner: HttpTransport, config?: Partial<RetryConfig>);
|
|
2014
|
+
get(url: string, headers?: HttpHeaders, signal?: AbortSignal): Promise<TransportResponse>;
|
|
2015
|
+
post(url: string, body: unknown, headers?: HttpHeaders, signal?: AbortSignal): Promise<Response>;
|
|
2016
|
+
private executeWithRetry;
|
|
2017
|
+
private isRetryableResponse;
|
|
2018
|
+
private getDelayForResponse;
|
|
2019
|
+
}
|
|
2020
|
+
|
|
2021
|
+
declare function isRetryableStatusCode(status: number, retryableStatusCodes?: number[]): boolean;
|
|
2022
|
+
declare function isRetryableError(error: unknown, retryableStatusCodes?: number[]): boolean;
|
|
2023
|
+
|
|
2024
|
+
interface BaseLLMOptions {
|
|
2025
|
+
enablePromptCaching?: boolean;
|
|
2026
|
+
retry?: Partial<RetryConfig>;
|
|
2027
|
+
}
|
|
1997
2028
|
declare class LLMError extends Error {
|
|
1998
2029
|
readonly statusCode?: number | undefined;
|
|
1999
2030
|
readonly isRetryable: boolean;
|
|
@@ -2003,9 +2034,8 @@ declare abstract class BaseLLM implements LLMPort {
|
|
|
2003
2034
|
protected transport: HttpTransport | null;
|
|
2004
2035
|
protected apiUrl: string;
|
|
2005
2036
|
protected enablePromptCaching: boolean;
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
});
|
|
2037
|
+
protected retryConfig?: Partial<RetryConfig>;
|
|
2038
|
+
constructor(apiUrl: string, options?: BaseLLMOptions);
|
|
2009
2039
|
protected abstract createTransport(): HttpTransport;
|
|
2010
2040
|
protected transformUsage(rawUsage: unknown): UsageData | undefined;
|
|
2011
2041
|
protected getTransport(): HttpTransport;
|
|
@@ -2038,11 +2068,12 @@ type GithubOptions = {
|
|
|
2038
2068
|
accessToken?: string;
|
|
2039
2069
|
apiUrl?: string;
|
|
2040
2070
|
httpLogFile?: string;
|
|
2071
|
+
retry?: Partial<RetryConfig>;
|
|
2041
2072
|
};
|
|
2042
2073
|
declare class GithubLLM extends BaseLLM implements LLMPort {
|
|
2043
2074
|
private readonly opts;
|
|
2044
2075
|
constructor(opts?: GithubOptions);
|
|
2045
|
-
protected createTransport(): GithubAuthTransport;
|
|
2076
|
+
protected createTransport(): GithubAuthTransport | RetryTransport;
|
|
2046
2077
|
protected transformUsage(rawUsage: unknown): UsageData | undefined;
|
|
2047
2078
|
getModels(signal?: AbortSignal): Promise<ModelInfo[]>;
|
|
2048
2079
|
private handleError;
|
|
@@ -2065,6 +2096,7 @@ type AnthropicAISDKOptions = {
|
|
|
2065
2096
|
apiUrl?: string;
|
|
2066
2097
|
baseURL?: string;
|
|
2067
2098
|
httpLogFile?: string;
|
|
2099
|
+
retry?: Partial<RetryConfig>;
|
|
2068
2100
|
onTokenUpdate?: (newCredentials: {
|
|
2069
2101
|
access: string;
|
|
2070
2102
|
refresh: string;
|
|
@@ -2074,12 +2106,11 @@ type AnthropicAISDKOptions = {
|
|
|
2074
2106
|
declare class AnthropicAISDKLLM {
|
|
2075
2107
|
private readonly opts;
|
|
2076
2108
|
private provider?;
|
|
2077
|
-
private
|
|
2109
|
+
private transport?;
|
|
2110
|
+
private authTransport?;
|
|
2078
2111
|
constructor(opts?: AnthropicAISDKOptions);
|
|
2079
|
-
private
|
|
2080
|
-
private
|
|
2081
|
-
private ensureValidToken;
|
|
2082
|
-
private createFetchWithRetry;
|
|
2112
|
+
private getAuthTransport;
|
|
2113
|
+
private getTransport;
|
|
2083
2114
|
private getProvider;
|
|
2084
2115
|
private getModel;
|
|
2085
2116
|
private transformMessages;
|
|
@@ -2109,6 +2140,7 @@ interface LLMOptions {
|
|
|
2109
2140
|
includeUsage?: boolean;
|
|
2110
2141
|
version?: string;
|
|
2111
2142
|
providerName?: string;
|
|
2143
|
+
retry?: Partial<RetryConfig>;
|
|
2112
2144
|
}
|
|
2113
2145
|
interface CustomProviderDefinition {
|
|
2114
2146
|
type?: 'openai-compat' | 'anthropic';
|
|
@@ -2211,4 +2243,4 @@ declare function resolveBackspaces(s: string): string;
|
|
|
2211
2243
|
declare function stripAnsiAndControls(s: string): string;
|
|
2212
2244
|
declare function canonicalizeTerminalPaste(raw: string): string;
|
|
2213
2245
|
|
|
2214
|
-
export { AGENT_CREATOR_SYSTEM_PROMPT, type AgentAwareToolPort, type AgentCatalog, type AgentConfig, type AgentEvent, AgentEventTypes, AgentFilePersistence, AgentManager, AgentManagerCommandRunner, AgentOrchestrator, AgentRegistry, type AgentTemplate, AnthropicAISDKLLM, type AssignErrorResult, type AssignParams, type AssignResult, type AssignSuccessResult$1 as AssignSuccessResult, type AssignTaskArgs, type AssignTaskMetadata, type BashErrorResult, type BashParams, type BashResult, type BashSuccessResult$1 as BashSuccessResult, BashTool, type BashToolArgs, type BashToolMetadata, type CommandMetadata, type CompleteAgent, CompositeToolPort, type Conversation, ConversationContext, type ConversationMetadata, type ConversationSnapshot, ConversationStore, CoreMCPClient, DefaultDelegationPolicy, DefaultDelegationResultFormatter, DefaultDelegationService, DefaultSpecialistAgentFactory, type DelegationMetadata, type DelegationService, type DelegationServiceConfig, DelegationServiceFactory, type DirEntry, type DirLsArgs, type DirLsMetadata, type DirLsParams, type DirLsResult, type DirLsSuccessResult$1 as DirLsSuccessResult, type ErrorMetadata, ErrorReason, type ExecResult, type ExecResultError, type ExecResultSuccess, type FileEditArgs, type FileEditMetadata, type FileEditResult, type FileEditSuccessResult$1 as FileEditSuccessResult, type FileMetadata, type FileNewArgs, type FileNewMetadata, type FileNewParams, type FileNewResult, type FileNewSuccessResult$1 as FileNewSuccessResult, type FileReadArgs, type FileReadErrorResult, type FileReadMetadata, type FileReadParams, type FileReadResult, type FileReadSuccessResult$1 as FileReadSuccessResult, type FolderTreeOptions, type FunctionTool, GithubLLM, InMemoryMemory, InMemoryMetadata, InMemoryMetricsPort, JsonFileMemoryPersistence, type LLMConfig, LLMError, type LLMFactory, type LLMOptions, type LLMPort, LLMResolver, type LineRangeMetadata, type MCPConfig, type MCPServerConfig, MCPToolPort, type MemoryPort, MemoryPortMetadataAdapter, type Message, type MessageContent, type MessageContentPart, type MetadataPort, type MetricsChangeHandler, type MetricsPort, type MetricsSnapshot, type ModelInfo, type ModelLimits, NoopMetricsPort, NoopReminders, type OrchestratorAwareToolPort, type ParseResult, PersistedMemory, PersistingConsoleEventPort, RuntimeEnv, type SendMessageOptions, SimpleContextBuilder, SimpleCost, SimpleId, type SpecialistAgentConfig, type SpecialistAgentResult, type SubAgentState, type SubAgentToolCall, SystemClock, type TodoWriteArgs, type TodoWriteMetadata, type TodoWriteResult, type TodoWriteSuccessResult$1 as TodoWriteSuccessResult, type ToolApprovalDecision, type ToolArguments, type ToolCall, type ToolCallValidation, type ToolErrorMetadata, type ToolExecutionContext, type ToolExecutionResult, type ToolMetadataMap, type ToolName, type ToolParameterMap, type ToolPort, ToolRegistry, type ToolValidator, type TypedToolInvocation, type UsageData, type UserAttachment, type UserMessagePayload, type ValidationResult, type WebFetchArgs, type WebFetchMetadata, type WebFetchParams, type WebFetchResult, type WebFetchSuccessResult$1 as WebFetchSuccessResult, type WebSearchArgs, type WebSearchMetadata, type WebSearchParams, type WebSearchResult, type WebSearchSuccessResult$1 as WebSearchSuccessResult, type WebSearchToolResult, buildAgentCreationPrompt, buildInjectedSystem, canonicalizeTerminalPaste, convertToolCall, convertToolCalls, createEmptySnapshot, createLLM, err, generateFolderTree, getAvailableProviders, getFallbackLimits, getProviderLabel, isAssignResult, isAssignSuccess, isAssignTaskArgs, isBashResult, isBashSuccess, isBashToolArgs, isDirLsArgs, isDirLsResult, isDirLsSuccess, isError, isFileEditArgs, isFileEditResult, isFileEditSuccess, isFileNewArgs, isFileNewResult, isFileNewSuccess, isFileReadArgs, isFileReadResult, isFileReadSuccess, isJsonResult, isSuccess, isSuccessJson, isSuccessText, isTextResult, isTodoWriteArgs, isTodoWriteResult, isTodoWriteSuccess, isWebFetchArgs, isWebFetchResult, isWebFetchSuccess, isWebSearchArgs, isWebSearchResult, isWebSearchSuccess, loadMCPConfig, normalizeModelInfo, normalizeModelLimits, normalizeNewlines, okJson, okText, parseJSON, parseSubAgentToolCallArguments, parseToolArguments, renderTemplate, resolveBackspaces, resolveCarriageReturns, stripAnsiAndControls, supportsGetModels, toolValidators };
|
|
2246
|
+
export { AGENT_CREATOR_SYSTEM_PROMPT, AbortError, type AgentAwareToolPort, type AgentCatalog, type AgentConfig, type AgentEvent, AgentEventTypes, AgentFilePersistence, AgentManager, AgentManagerCommandRunner, AgentOrchestrator, AgentRegistry, type AgentTemplate, AnthropicAISDKLLM, type AssignErrorResult, type AssignParams, type AssignResult, type AssignSuccessResult$1 as AssignSuccessResult, type AssignTaskArgs, type AssignTaskMetadata, type BaseLLMOptions, type BashErrorResult, type BashParams, type BashResult, type BashSuccessResult$1 as BashSuccessResult, BashTool, type BashToolArgs, type BashToolMetadata, type CommandMetadata, type CompleteAgent, CompositeToolPort, type Conversation, ConversationContext, type ConversationMetadata, type ConversationSnapshot, ConversationStore, CoreMCPClient, DEFAULT_RETRY_CONFIG, DefaultDelegationPolicy, DefaultDelegationResultFormatter, DefaultDelegationService, DefaultSpecialistAgentFactory, type DelegationMetadata, type DelegationService, type DelegationServiceConfig, DelegationServiceFactory, type DirEntry, type DirLsArgs, type DirLsMetadata, type DirLsParams, type DirLsResult, type DirLsSuccessResult$1 as DirLsSuccessResult, type ErrorMetadata, ErrorReason, type ExecResult, type ExecResultError, type ExecResultSuccess, type FileEditArgs, type FileEditMetadata, type FileEditResult, type FileEditSuccessResult$1 as FileEditSuccessResult, type FileMetadata, type FileNewArgs, type FileNewMetadata, type FileNewParams, type FileNewResult, type FileNewSuccessResult$1 as FileNewSuccessResult, type FileReadArgs, type FileReadErrorResult, type FileReadMetadata, type FileReadParams, type FileReadResult, type FileReadSuccessResult$1 as FileReadSuccessResult, type FolderTreeOptions, type FunctionTool, GithubLLM, InMemoryMemory, InMemoryMetadata, InMemoryMetricsPort, JsonFileMemoryPersistence, type LLMConfig, LLMError, type LLMFactory, type LLMOptions, type LLMPort, LLMResolver, type LineRangeMetadata, type MCPConfig, type MCPServerConfig, MCPToolPort, type MemoryPort, MemoryPortMetadataAdapter, type Message, type MessageContent, type MessageContentPart, type MetadataPort, type MetricsChangeHandler, type MetricsPort, type MetricsSnapshot, type ModelInfo, type ModelLimits, NoopMetricsPort, NoopReminders, type OrchestratorAwareToolPort, type ParseResult, PersistedMemory, PersistingConsoleEventPort, type RetryConfig, RetryTransport, RuntimeEnv, type SendMessageOptions, SimpleContextBuilder, SimpleCost, SimpleId, type SpecialistAgentConfig, type SpecialistAgentResult, type SubAgentState, type SubAgentToolCall, SystemClock, type TodoWriteArgs, type TodoWriteMetadata, type TodoWriteResult, type TodoWriteSuccessResult$1 as TodoWriteSuccessResult, type ToolApprovalDecision, type ToolArguments, type ToolCall, type ToolCallValidation, type ToolErrorMetadata, type ToolExecutionContext, type ToolExecutionResult, type ToolMetadataMap, type ToolName, type ToolParameterMap, type ToolPort, ToolRegistry, type ToolValidator, type TypedToolInvocation, type UsageData, type UserAttachment, type UserMessagePayload, type ValidationResult, type WebFetchArgs, type WebFetchMetadata, type WebFetchParams, type WebFetchResult, type WebFetchSuccessResult$1 as WebFetchSuccessResult, type WebSearchArgs, type WebSearchMetadata, type WebSearchParams, type WebSearchResult, type WebSearchSuccessResult$1 as WebSearchSuccessResult, type WebSearchToolResult, buildAgentCreationPrompt, buildInjectedSystem, canonicalizeTerminalPaste, convertToolCall, convertToolCalls, createEmptySnapshot, createLLM, err, generateFolderTree, getAvailableProviders, getFallbackLimits, getProviderLabel, isAssignResult, isAssignSuccess, isAssignTaskArgs, isBashResult, isBashSuccess, isBashToolArgs, isDirLsArgs, isDirLsResult, isDirLsSuccess, isError, isFileEditArgs, isFileEditResult, isFileEditSuccess, isFileNewArgs, isFileNewResult, isFileNewSuccess, isFileReadArgs, isFileReadResult, isFileReadSuccess, isJsonResult, isRetryableError, isRetryableStatusCode, isSuccess, isSuccessJson, isSuccessText, isTextResult, isTodoWriteArgs, isTodoWriteResult, isTodoWriteSuccess, isWebFetchArgs, isWebFetchResult, isWebFetchSuccess, isWebSearchArgs, isWebSearchResult, isWebSearchSuccess, loadMCPConfig, normalizeModelInfo, normalizeModelLimits, normalizeNewlines, okJson, okText, parseJSON, parseSubAgentToolCallArguments, parseToolArguments, renderTemplate, resolveBackspaces, resolveCarriageReturns, stripAnsiAndControls, supportsGetModels, toolValidators };
|
package/dist/index.js
CHANGED
|
@@ -1015,37 +1015,30 @@ var AgentOrchestrator = class {
|
|
|
1015
1015
|
if (!_llm) {
|
|
1016
1016
|
throw new Error("LLM provider not set");
|
|
1017
1017
|
}
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1018
|
+
const normalized = typeof content === "string" ? { text: content, displayText: content, attachments: [] } : {
|
|
1019
|
+
text: content.text ?? "",
|
|
1020
|
+
displayText: content.displayText,
|
|
1021
|
+
attachments: Array.isArray(content.attachments) ? content.attachments : []
|
|
1022
|
+
};
|
|
1023
|
+
const attachments = normalized.attachments;
|
|
1024
|
+
enhanced = this.reminders.enhance(normalized.text, { conversationId: convo });
|
|
1025
|
+
const enhancedCombined = enhanced.join("\n");
|
|
1026
|
+
const messageParts = buildMessageParts(enhancedCombined, attachments);
|
|
1027
|
+
let userContent;
|
|
1028
|
+
if (attachments.length > 0 || messageParts.some((part) => part.type === "image")) {
|
|
1029
|
+
userContent = { type: "parts", parts: messageParts };
|
|
1030
|
+
} else if (messageParts.length === 1 && messageParts[0]?.type === "text") {
|
|
1031
|
+
userContent = messageParts[0].text;
|
|
1032
|
+
} else if (messageParts.length > 0) {
|
|
1033
|
+
userContent = { type: "parts", parts: messageParts };
|
|
1023
1034
|
} else {
|
|
1024
|
-
|
|
1025
|
-
text: content.text ?? "",
|
|
1026
|
-
displayText: content.displayText,
|
|
1027
|
-
attachments: Array.isArray(content.attachments) ? content.attachments : []
|
|
1028
|
-
};
|
|
1029
|
-
const attachments = normalized.attachments;
|
|
1030
|
-
enhanced = this.reminders.enhance(normalized.text, { conversationId: convo });
|
|
1031
|
-
const enhancedCombined = enhanced.join("\n");
|
|
1032
|
-
const messageParts = buildMessageParts(enhancedCombined, attachments);
|
|
1033
|
-
let userContent;
|
|
1034
|
-
if (attachments.length > 0 || messageParts.some((part) => part.type === "image")) {
|
|
1035
|
-
userContent = { type: "parts", parts: messageParts };
|
|
1036
|
-
} else if (messageParts.length === 1 && messageParts[0]?.type === "text") {
|
|
1037
|
-
userContent = messageParts[0].text;
|
|
1038
|
-
} else if (messageParts.length > 0) {
|
|
1039
|
-
userContent = { type: "parts", parts: messageParts };
|
|
1040
|
-
} else {
|
|
1041
|
-
userContent = enhancedCombined;
|
|
1042
|
-
}
|
|
1043
|
-
providerMsgs = this.context.toProviderMessages(history, this.cfg.systemPrompt, [userContent]);
|
|
1044
|
-
userDisplay = resolveDisplayText(normalized.text, attachments, normalized.displayText);
|
|
1045
|
-
const userTimestamp = this.clock.iso();
|
|
1046
|
-
userMessages = [{ id: this.ids.uuid(), role: "user", content: userContent, timestamp: userTimestamp }];
|
|
1047
|
-
await this.memory.append(convo, userMessages);
|
|
1035
|
+
userContent = enhancedCombined;
|
|
1048
1036
|
}
|
|
1037
|
+
providerMsgs = this.context.toProviderMessages(history, this.cfg.systemPrompt, [userContent]);
|
|
1038
|
+
userDisplay = resolveDisplayText(normalized.text, attachments, normalized.displayText);
|
|
1039
|
+
const userTimestamp = this.clock.iso();
|
|
1040
|
+
userMessages = [{ id: this.ids.uuid(), role: "user", content: userContent, timestamp: userTimestamp }];
|
|
1041
|
+
await this.memory.append(convo, userMessages);
|
|
1049
1042
|
if (opts.signal?.aborted) throw new Error("Aborted");
|
|
1050
1043
|
const toolDefs = this.tools.getToolDefinitions(this.cfg.enabledTools ?? []);
|
|
1051
1044
|
const toolNames = toolDefs.map((t) => t.function.name);
|
|
@@ -1212,7 +1205,10 @@ var AgentOrchestrator = class {
|
|
|
1212
1205
|
content: contentStr,
|
|
1213
1206
|
timestamp: this.clock.iso(),
|
|
1214
1207
|
tool_call_id: tr.id,
|
|
1215
|
-
name: tr.name
|
|
1208
|
+
name: tr.name,
|
|
1209
|
+
status: tr.status,
|
|
1210
|
+
durationMs: tr.durationMs,
|
|
1211
|
+
metadata: tr.metadata
|
|
1216
1212
|
});
|
|
1217
1213
|
this.metrics?.recordToolCall?.();
|
|
1218
1214
|
await this.events?.emit({
|
|
@@ -3751,7 +3747,7 @@ var AgentManager = class {
|
|
|
3751
3747
|
}
|
|
3752
3748
|
};
|
|
3753
3749
|
}
|
|
3754
|
-
this.eventCallback?.({
|
|
3750
|
+
await this.eventCallback?.({
|
|
3755
3751
|
type: AgentEventTypes.SubAgentStarted,
|
|
3756
3752
|
conversationId: config.conversationId ?? "default",
|
|
3757
3753
|
messageId: config.messageId ?? "",
|
|
@@ -3770,7 +3766,7 @@ var AgentManager = class {
|
|
|
3770
3766
|
events.push(event);
|
|
3771
3767
|
if (event.type === AgentEventTypes.ToolCalls) {
|
|
3772
3768
|
for (const toolCall of event.toolCalls) {
|
|
3773
|
-
this.eventCallback?.({
|
|
3769
|
+
await this.eventCallback?.({
|
|
3774
3770
|
type: AgentEventTypes.SubAgentToolCall,
|
|
3775
3771
|
conversationId: config.conversationId ?? "default",
|
|
3776
3772
|
messageId: config.messageId ?? "",
|
|
@@ -3781,7 +3777,7 @@ var AgentManager = class {
|
|
|
3781
3777
|
});
|
|
3782
3778
|
}
|
|
3783
3779
|
} else if (event.type === AgentEventTypes.ToolResult) {
|
|
3784
|
-
this.eventCallback?.({
|
|
3780
|
+
await this.eventCallback?.({
|
|
3785
3781
|
type: AgentEventTypes.SubAgentToolResult,
|
|
3786
3782
|
conversationId: config.conversationId ?? "default",
|
|
3787
3783
|
messageId: config.messageId ?? "",
|
|
@@ -3845,7 +3841,7 @@ var AgentManager = class {
|
|
|
3845
3841
|
}
|
|
3846
3842
|
}
|
|
3847
3843
|
const snapshot = metricsPort.getSnapshot();
|
|
3848
|
-
this.eventCallback?.({
|
|
3844
|
+
await this.eventCallback?.({
|
|
3849
3845
|
type: AgentEventTypes.SubAgentCompleted,
|
|
3850
3846
|
conversationId: config.conversationId ?? "default",
|
|
3851
3847
|
messageId: config.messageId ?? "",
|
|
@@ -3875,7 +3871,7 @@ var AgentManager = class {
|
|
|
3875
3871
|
const isTimeout = error instanceof Error && error.message.includes("timeout");
|
|
3876
3872
|
const isAborted = error instanceof Error && (error.message.includes("aborted") || error.name === "AbortError");
|
|
3877
3873
|
const status = isTimeout ? "timeout" : isAborted ? "error" : "error";
|
|
3878
|
-
this.eventCallback?.({
|
|
3874
|
+
await this.eventCallback?.({
|
|
3879
3875
|
type: AgentEventTypes.SubAgentCompleted,
|
|
3880
3876
|
conversationId: config.conversationId ?? "default",
|
|
3881
3877
|
messageId: config.messageId ?? "",
|
|
@@ -4634,9 +4630,11 @@ var BaseLLM = class {
|
|
|
4634
4630
|
transport = null;
|
|
4635
4631
|
apiUrl;
|
|
4636
4632
|
enablePromptCaching = false;
|
|
4633
|
+
retryConfig;
|
|
4637
4634
|
constructor(apiUrl, options) {
|
|
4638
4635
|
this.apiUrl = apiUrl;
|
|
4639
4636
|
this.enablePromptCaching = options?.enablePromptCaching ?? false;
|
|
4637
|
+
this.retryConfig = options?.retry;
|
|
4640
4638
|
}
|
|
4641
4639
|
transformUsage(rawUsage) {
|
|
4642
4640
|
if (!rawUsage) return void 0;
|
|
@@ -5239,6 +5237,387 @@ var GithubAuthTransport = class {
|
|
|
5239
5237
|
}
|
|
5240
5238
|
};
|
|
5241
5239
|
|
|
5240
|
+
// src/transports/backoff.ts
|
|
5241
|
+
function calculateBackoff(attempt, baseDelayMs, maxDelayMs, multiplier, jitterFactor) {
|
|
5242
|
+
const exponentialDelay = baseDelayMs * multiplier ** attempt;
|
|
5243
|
+
const cappedDelay = Math.min(exponentialDelay, maxDelayMs);
|
|
5244
|
+
const jitterRange = cappedDelay * jitterFactor;
|
|
5245
|
+
const jitter = jitterRange * (Math.random() * 2 - 1);
|
|
5246
|
+
return Math.max(0, Math.round(cappedDelay + jitter));
|
|
5247
|
+
}
|
|
5248
|
+
function parseRetryAfterHeader(header) {
|
|
5249
|
+
if (!header) return null;
|
|
5250
|
+
const seconds = parseInt(header, 10);
|
|
5251
|
+
if (!Number.isNaN(seconds) && seconds >= 0) {
|
|
5252
|
+
return seconds * 1e3;
|
|
5253
|
+
}
|
|
5254
|
+
const date = Date.parse(header);
|
|
5255
|
+
if (!Number.isNaN(date)) {
|
|
5256
|
+
const delayMs = date - Date.now();
|
|
5257
|
+
return delayMs > 0 ? delayMs : null;
|
|
5258
|
+
}
|
|
5259
|
+
return null;
|
|
5260
|
+
}
|
|
5261
|
+
|
|
5262
|
+
// src/transports/error-classification.ts
|
|
5263
|
+
var DEFAULT_RETRYABLE_STATUS_CODES = [429, 500, 502, 503, 504];
|
|
5264
|
+
var RETRYABLE_NETWORK_ERRORS = [
|
|
5265
|
+
"econnrefused",
|
|
5266
|
+
"enotfound",
|
|
5267
|
+
"etimedout",
|
|
5268
|
+
"econnreset",
|
|
5269
|
+
"epipe",
|
|
5270
|
+
"network",
|
|
5271
|
+
"fetch failed",
|
|
5272
|
+
"socket hang up"
|
|
5273
|
+
];
|
|
5274
|
+
var NON_RETRYABLE_PATTERNS = [
|
|
5275
|
+
"invalid",
|
|
5276
|
+
"unauthorized",
|
|
5277
|
+
"forbidden",
|
|
5278
|
+
"not found",
|
|
5279
|
+
"bad request",
|
|
5280
|
+
"api key",
|
|
5281
|
+
"authentication",
|
|
5282
|
+
"permission",
|
|
5283
|
+
"invalid_api_key",
|
|
5284
|
+
"insufficient_quota"
|
|
5285
|
+
];
|
|
5286
|
+
function isRetryableStatusCode(status, retryableStatusCodes = DEFAULT_RETRYABLE_STATUS_CODES) {
|
|
5287
|
+
return retryableStatusCodes.includes(status);
|
|
5288
|
+
}
|
|
5289
|
+
function isRetryableError(error, retryableStatusCodes = DEFAULT_RETRYABLE_STATUS_CODES) {
|
|
5290
|
+
if (!error) return false;
|
|
5291
|
+
if (error instanceof Error && error.name === "AbortError") {
|
|
5292
|
+
return false;
|
|
5293
|
+
}
|
|
5294
|
+
if (error instanceof LLMError) {
|
|
5295
|
+
if (error.statusCode) {
|
|
5296
|
+
return isRetryableStatusCode(error.statusCode, retryableStatusCodes);
|
|
5297
|
+
}
|
|
5298
|
+
return error.isRetryable;
|
|
5299
|
+
}
|
|
5300
|
+
const err2 = error;
|
|
5301
|
+
const statusCode = err2.statusCode ?? err2.status;
|
|
5302
|
+
if (statusCode) {
|
|
5303
|
+
return isRetryableStatusCode(statusCode, retryableStatusCodes);
|
|
5304
|
+
}
|
|
5305
|
+
const message = err2.message?.toLowerCase() || "";
|
|
5306
|
+
const code = err2.code?.toLowerCase() || "";
|
|
5307
|
+
for (const pattern of NON_RETRYABLE_PATTERNS) {
|
|
5308
|
+
if (message.includes(pattern) || code.includes(pattern)) {
|
|
5309
|
+
return false;
|
|
5310
|
+
}
|
|
5311
|
+
}
|
|
5312
|
+
for (const networkError of RETRYABLE_NETWORK_ERRORS) {
|
|
5313
|
+
if (message.includes(networkError) || code.includes(networkError)) {
|
|
5314
|
+
return true;
|
|
5315
|
+
}
|
|
5316
|
+
}
|
|
5317
|
+
return false;
|
|
5318
|
+
}
|
|
5319
|
+
|
|
5320
|
+
// src/transports/retry-transport.ts
|
|
5321
|
+
var DEFAULT_RETRY_CONFIG = {
|
|
5322
|
+
maxRetries: 3,
|
|
5323
|
+
baseDelayMs: 1e3,
|
|
5324
|
+
maxDelayMs: 6e4,
|
|
5325
|
+
backoffMultiplier: 2,
|
|
5326
|
+
jitterFactor: 0.2,
|
|
5327
|
+
retryableStatusCodes: [429, 500, 502, 503, 504]
|
|
5328
|
+
};
|
|
5329
|
+
var AbortError = class _AbortError extends Error {
|
|
5330
|
+
constructor(message = "Operation aborted") {
|
|
5331
|
+
super(message);
|
|
5332
|
+
this.name = "AbortError";
|
|
5333
|
+
if (Error.captureStackTrace) {
|
|
5334
|
+
Error.captureStackTrace(this, _AbortError);
|
|
5335
|
+
}
|
|
5336
|
+
}
|
|
5337
|
+
};
|
|
5338
|
+
var sleep = (ms, signal) => {
|
|
5339
|
+
return new Promise((resolve6, reject) => {
|
|
5340
|
+
if (signal?.aborted) {
|
|
5341
|
+
reject(new AbortError("Operation aborted"));
|
|
5342
|
+
return;
|
|
5343
|
+
}
|
|
5344
|
+
const timeout = setTimeout(resolve6, ms);
|
|
5345
|
+
signal?.addEventListener(
|
|
5346
|
+
"abort",
|
|
5347
|
+
() => {
|
|
5348
|
+
clearTimeout(timeout);
|
|
5349
|
+
reject(new AbortError("Operation aborted during retry delay"));
|
|
5350
|
+
},
|
|
5351
|
+
{ once: true }
|
|
5352
|
+
);
|
|
5353
|
+
});
|
|
5354
|
+
};
|
|
5355
|
+
var RetryTransport = class {
|
|
5356
|
+
constructor(inner, config = {}) {
|
|
5357
|
+
this.inner = inner;
|
|
5358
|
+
this.config = { ...DEFAULT_RETRY_CONFIG, ...config };
|
|
5359
|
+
}
|
|
5360
|
+
config;
|
|
5361
|
+
async get(url, headers, signal) {
|
|
5362
|
+
return this.executeWithRetry(() => this.inner.get(url, headers, signal), signal);
|
|
5363
|
+
}
|
|
5364
|
+
async post(url, body, headers, signal) {
|
|
5365
|
+
return this.executeWithRetry(() => this.inner.post(url, body, headers, signal), signal);
|
|
5366
|
+
}
|
|
5367
|
+
async executeWithRetry(fn, signal) {
|
|
5368
|
+
let lastError;
|
|
5369
|
+
let attempt = 0;
|
|
5370
|
+
while (attempt <= this.config.maxRetries) {
|
|
5371
|
+
if (signal?.aborted) {
|
|
5372
|
+
throw new AbortError("Operation aborted before execution");
|
|
5373
|
+
}
|
|
5374
|
+
try {
|
|
5375
|
+
const response = await fn();
|
|
5376
|
+
if (this.isRetryableResponse(response)) {
|
|
5377
|
+
const error = new Error(`HTTP ${response.status}`);
|
|
5378
|
+
error.status = response.status;
|
|
5379
|
+
if (attempt < this.config.maxRetries) {
|
|
5380
|
+
const delayMs = this.getDelayForResponse(response, attempt);
|
|
5381
|
+
this.config.onRetry?.(attempt + 1, error, delayMs);
|
|
5382
|
+
await sleep(delayMs, signal);
|
|
5383
|
+
attempt++;
|
|
5384
|
+
continue;
|
|
5385
|
+
}
|
|
5386
|
+
lastError = error;
|
|
5387
|
+
break;
|
|
5388
|
+
}
|
|
5389
|
+
return response;
|
|
5390
|
+
} catch (error) {
|
|
5391
|
+
if (error instanceof AbortError || error instanceof Error && error.name === "AbortError") {
|
|
5392
|
+
throw error;
|
|
5393
|
+
}
|
|
5394
|
+
lastError = error instanceof Error ? error : new Error(String(error));
|
|
5395
|
+
if (!isRetryableError(lastError, this.config.retryableStatusCodes)) {
|
|
5396
|
+
throw lastError;
|
|
5397
|
+
}
|
|
5398
|
+
if (attempt < this.config.maxRetries) {
|
|
5399
|
+
const delayMs = calculateBackoff(
|
|
5400
|
+
attempt,
|
|
5401
|
+
this.config.baseDelayMs,
|
|
5402
|
+
this.config.maxDelayMs,
|
|
5403
|
+
this.config.backoffMultiplier,
|
|
5404
|
+
this.config.jitterFactor
|
|
5405
|
+
);
|
|
5406
|
+
this.config.onRetry?.(attempt + 1, lastError, delayMs);
|
|
5407
|
+
await sleep(delayMs, signal);
|
|
5408
|
+
attempt++;
|
|
5409
|
+
} else {
|
|
5410
|
+
break;
|
|
5411
|
+
}
|
|
5412
|
+
}
|
|
5413
|
+
}
|
|
5414
|
+
if (lastError) {
|
|
5415
|
+
this.config.onExhausted?.(lastError, attempt + 1);
|
|
5416
|
+
throw lastError;
|
|
5417
|
+
}
|
|
5418
|
+
throw new Error("Retry exhausted without error");
|
|
5419
|
+
}
|
|
5420
|
+
isRetryableResponse(response) {
|
|
5421
|
+
return isRetryableStatusCode(response.status, this.config.retryableStatusCodes);
|
|
5422
|
+
}
|
|
5423
|
+
getDelayForResponse(response, attempt) {
|
|
5424
|
+
const headers = "headers" in response && response.headers instanceof Headers ? response.headers : null;
|
|
5425
|
+
const retryAfter = headers?.get("retry-after") ?? null;
|
|
5426
|
+
const retryAfterMs = parseRetryAfterHeader(retryAfter);
|
|
5427
|
+
if (retryAfterMs !== null) {
|
|
5428
|
+
return Math.min(retryAfterMs, this.config.maxDelayMs);
|
|
5429
|
+
}
|
|
5430
|
+
return calculateBackoff(
|
|
5431
|
+
attempt,
|
|
5432
|
+
this.config.baseDelayMs,
|
|
5433
|
+
this.config.maxDelayMs,
|
|
5434
|
+
this.config.backoffMultiplier,
|
|
5435
|
+
this.config.jitterFactor
|
|
5436
|
+
);
|
|
5437
|
+
}
|
|
5438
|
+
};
|
|
5439
|
+
|
|
5440
|
+
// src/transports/anthropic-transport.ts
|
|
5441
|
+
var CLIENT_ID = "9d1c250a-e61b-44d9-88ed-5944d1962f5e";
|
|
5442
|
+
var DEFAULT_BASE_URL = "https://api.anthropic.com/v1";
|
|
5443
|
+
var AnthropicAuthTransport = class {
|
|
5444
|
+
inner;
|
|
5445
|
+
baseUrl;
|
|
5446
|
+
retryConfig;
|
|
5447
|
+
apiKey;
|
|
5448
|
+
oauth;
|
|
5449
|
+
onTokenUpdate;
|
|
5450
|
+
refreshPromise = null;
|
|
5451
|
+
constructor(inner, opts) {
|
|
5452
|
+
this.inner = inner;
|
|
5453
|
+
this.apiKey = opts.apiKey;
|
|
5454
|
+
this.oauth = opts.oauth;
|
|
5455
|
+
this.baseUrl = opts.baseUrl ?? DEFAULT_BASE_URL;
|
|
5456
|
+
this.onTokenUpdate = opts.onTokenUpdate;
|
|
5457
|
+
this.retryConfig = opts.retry;
|
|
5458
|
+
}
|
|
5459
|
+
async refreshAccessToken() {
|
|
5460
|
+
if (!this.oauth) {
|
|
5461
|
+
return { type: "failed" };
|
|
5462
|
+
}
|
|
5463
|
+
try {
|
|
5464
|
+
const response = await fetch("https://console.anthropic.com/v1/oauth/token", {
|
|
5465
|
+
method: "POST",
|
|
5466
|
+
headers: {
|
|
5467
|
+
"Content-Type": "application/json"
|
|
5468
|
+
},
|
|
5469
|
+
body: JSON.stringify({
|
|
5470
|
+
grant_type: "refresh_token",
|
|
5471
|
+
refresh_token: this.oauth.refresh,
|
|
5472
|
+
client_id: CLIENT_ID
|
|
5473
|
+
})
|
|
5474
|
+
});
|
|
5475
|
+
if (!response.ok) {
|
|
5476
|
+
return { type: "failed" };
|
|
5477
|
+
}
|
|
5478
|
+
const json = await response.json();
|
|
5479
|
+
return {
|
|
5480
|
+
type: "success",
|
|
5481
|
+
access: json.access_token,
|
|
5482
|
+
refresh: json.refresh_token,
|
|
5483
|
+
expires: Date.now() + json.expires_in * 1e3
|
|
5484
|
+
};
|
|
5485
|
+
} catch {
|
|
5486
|
+
return { type: "failed" };
|
|
5487
|
+
}
|
|
5488
|
+
}
|
|
5489
|
+
updateCredentials(result) {
|
|
5490
|
+
if (result.type === "success" && result.access && result.refresh && result.expires) {
|
|
5491
|
+
if (this.oauth) {
|
|
5492
|
+
this.oauth.access = result.access;
|
|
5493
|
+
this.oauth.refresh = result.refresh;
|
|
5494
|
+
this.oauth.expires = result.expires;
|
|
5495
|
+
}
|
|
5496
|
+
this.onTokenUpdate?.({
|
|
5497
|
+
access: result.access,
|
|
5498
|
+
refresh: result.refresh,
|
|
5499
|
+
expires: result.expires
|
|
5500
|
+
});
|
|
5501
|
+
}
|
|
5502
|
+
}
|
|
5503
|
+
async ensureValidToken() {
|
|
5504
|
+
if (!this.oauth) return;
|
|
5505
|
+
if (this.refreshPromise) {
|
|
5506
|
+
const result = await this.refreshPromise;
|
|
5507
|
+
if (result.type === "failed") {
|
|
5508
|
+
throw new Error("Token refresh failed");
|
|
5509
|
+
}
|
|
5510
|
+
return;
|
|
5511
|
+
}
|
|
5512
|
+
this.refreshPromise = this.refreshAccessToken();
|
|
5513
|
+
try {
|
|
5514
|
+
const result = await this.refreshPromise;
|
|
5515
|
+
if (result.type === "success") {
|
|
5516
|
+
this.updateCredentials(result);
|
|
5517
|
+
} else {
|
|
5518
|
+
throw new Error("Token refresh failed");
|
|
5519
|
+
}
|
|
5520
|
+
} finally {
|
|
5521
|
+
this.refreshPromise = null;
|
|
5522
|
+
}
|
|
5523
|
+
}
|
|
5524
|
+
buildFullUrl(path9) {
|
|
5525
|
+
if (path9.startsWith("/")) {
|
|
5526
|
+
return `${this.baseUrl}${path9}`;
|
|
5527
|
+
}
|
|
5528
|
+
return path9;
|
|
5529
|
+
}
|
|
5530
|
+
makeAuthHeaders(headers) {
|
|
5531
|
+
const base = {
|
|
5532
|
+
"anthropic-version": "2023-06-01",
|
|
5533
|
+
"anthropic-beta": "oauth-2025-04-20,fine-grained-tool-streaming-2025-05-14",
|
|
5534
|
+
...headers || {}
|
|
5535
|
+
};
|
|
5536
|
+
if (this.oauth) {
|
|
5537
|
+
base.authorization = `Bearer ${this.oauth.access}`;
|
|
5538
|
+
} else if (this.apiKey) {
|
|
5539
|
+
base["x-api-key"] = this.apiKey;
|
|
5540
|
+
}
|
|
5541
|
+
return base;
|
|
5542
|
+
}
|
|
5543
|
+
async get(url, headers, signal) {
|
|
5544
|
+
const fullUrl = this.buildFullUrl(url);
|
|
5545
|
+
let res = await this.inner.get(fullUrl, this.makeAuthHeaders(headers), signal);
|
|
5546
|
+
if ((res.status === 401 || res.status === 403) && this.oauth) {
|
|
5547
|
+
await this.ensureValidToken();
|
|
5548
|
+
res = await this.inner.get(fullUrl, this.makeAuthHeaders(headers), signal);
|
|
5549
|
+
}
|
|
5550
|
+
return res;
|
|
5551
|
+
}
|
|
5552
|
+
async post(url, body, headers, signal) {
|
|
5553
|
+
const fullUrl = this.buildFullUrl(url);
|
|
5554
|
+
let res = await this.inner.post(fullUrl, body, this.makeAuthHeaders(headers), signal);
|
|
5555
|
+
if ((res.status === 401 || res.status === 403) && this.oauth) {
|
|
5556
|
+
await this.ensureValidToken();
|
|
5557
|
+
res = await this.inner.post(fullUrl, body, this.makeAuthHeaders(headers), signal);
|
|
5558
|
+
}
|
|
5559
|
+
return res;
|
|
5560
|
+
}
|
|
5561
|
+
createRetryTransport() {
|
|
5562
|
+
return new RetryTransport(this, this.retryConfig);
|
|
5563
|
+
}
|
|
5564
|
+
createFetchFunction() {
|
|
5565
|
+
const makeRequest = async (url, init) => {
|
|
5566
|
+
let currentInit = init;
|
|
5567
|
+
if (this.oauth) {
|
|
5568
|
+
const headers = new Headers(currentInit?.headers);
|
|
5569
|
+
headers.delete("x-api-key");
|
|
5570
|
+
headers.set("authorization", `Bearer ${this.oauth.access}`);
|
|
5571
|
+
headers.set("user-agent", "ai-sdk/anthropic/2.0.30 ai-sdk/provider-utils/3.0.12");
|
|
5572
|
+
currentInit = { ...currentInit, headers };
|
|
5573
|
+
}
|
|
5574
|
+
const response = await fetch(url, currentInit);
|
|
5575
|
+
if ((response.status === 401 || response.status === 403) && this.oauth) {
|
|
5576
|
+
await this.ensureValidToken();
|
|
5577
|
+
const headers = new Headers(currentInit?.headers);
|
|
5578
|
+
headers.set("authorization", `Bearer ${this.oauth.access}`);
|
|
5579
|
+
currentInit = { ...currentInit, headers };
|
|
5580
|
+
return fetch(url, currentInit);
|
|
5581
|
+
}
|
|
5582
|
+
return response;
|
|
5583
|
+
};
|
|
5584
|
+
const retryTransport = new RetryTransport(
|
|
5585
|
+
{
|
|
5586
|
+
get: async (url, headers, signal) => {
|
|
5587
|
+
return makeRequest(url, { method: "GET", headers, signal });
|
|
5588
|
+
},
|
|
5589
|
+
post: async (url, body, headers, signal) => {
|
|
5590
|
+
return makeRequest(url, {
|
|
5591
|
+
method: "POST",
|
|
5592
|
+
headers,
|
|
5593
|
+
body: typeof body === "string" ? body : JSON.stringify(body),
|
|
5594
|
+
signal
|
|
5595
|
+
});
|
|
5596
|
+
}
|
|
5597
|
+
},
|
|
5598
|
+
this.retryConfig
|
|
5599
|
+
);
|
|
5600
|
+
return async (url, init) => {
|
|
5601
|
+
const urlStr = typeof url === "string" ? url : url instanceof URL ? url.toString() : url.url;
|
|
5602
|
+
const method = init?.method?.toUpperCase() ?? "GET";
|
|
5603
|
+
const headers = init?.headers ? Object.fromEntries(new Headers(init.headers).entries()) : void 0;
|
|
5604
|
+
if (method === "GET") {
|
|
5605
|
+
return retryTransport.get(urlStr, headers, init?.signal ?? void 0);
|
|
5606
|
+
}
|
|
5607
|
+
return retryTransport.post(urlStr, init?.body, headers, init?.signal ?? void 0);
|
|
5608
|
+
};
|
|
5609
|
+
}
|
|
5610
|
+
getBaseUrl() {
|
|
5611
|
+
return this.baseUrl;
|
|
5612
|
+
}
|
|
5613
|
+
getOAuth() {
|
|
5614
|
+
return this.oauth;
|
|
5615
|
+
}
|
|
5616
|
+
getApiKey() {
|
|
5617
|
+
return this.apiKey;
|
|
5618
|
+
}
|
|
5619
|
+
};
|
|
5620
|
+
|
|
5242
5621
|
// src/transports/base-bearer-auth-transport.ts
|
|
5243
5622
|
var BaseBearerAuthTransport = class {
|
|
5244
5623
|
inner;
|
|
@@ -5416,7 +5795,7 @@ function normalizeModelInfo(provider, model) {
|
|
|
5416
5795
|
var GithubLLM = class extends BaseLLM {
|
|
5417
5796
|
opts;
|
|
5418
5797
|
constructor(opts = {}) {
|
|
5419
|
-
super(opts.apiUrl ?? "https://api.individual.githubcopilot.com");
|
|
5798
|
+
super(opts.apiUrl ?? "https://api.individual.githubcopilot.com", { retry: opts.retry });
|
|
5420
5799
|
this.opts = opts;
|
|
5421
5800
|
}
|
|
5422
5801
|
createTransport() {
|
|
@@ -5427,11 +5806,15 @@ var GithubLLM = class extends BaseLLM {
|
|
|
5427
5806
|
maxFileSize: 5 * 1024 * 1024,
|
|
5428
5807
|
captureResponseBody: true
|
|
5429
5808
|
});
|
|
5430
|
-
|
|
5809
|
+
const authTransport = new GithubAuthTransport(base, {
|
|
5431
5810
|
baseUrl: this.opts.apiUrl,
|
|
5432
5811
|
apiKey: this.opts.apiKey,
|
|
5433
5812
|
accessToken: this.opts.accessToken
|
|
5434
5813
|
});
|
|
5814
|
+
if (this.retryConfig) {
|
|
5815
|
+
return new RetryTransport(authTransport, this.retryConfig);
|
|
5816
|
+
}
|
|
5817
|
+
return authTransport;
|
|
5435
5818
|
}
|
|
5436
5819
|
transformUsage(rawUsage) {
|
|
5437
5820
|
if (!rawUsage) return void 0;
|
|
@@ -5497,126 +5880,68 @@ import {
|
|
|
5497
5880
|
jsonSchema,
|
|
5498
5881
|
APICallError
|
|
5499
5882
|
} from "ai";
|
|
5500
|
-
var CLIENT_ID = "9d1c250a-e61b-44d9-88ed-5944d1962f5e";
|
|
5501
5883
|
var AnthropicAISDKLLM = class {
|
|
5502
5884
|
opts;
|
|
5503
5885
|
provider;
|
|
5504
|
-
|
|
5886
|
+
transport;
|
|
5887
|
+
authTransport;
|
|
5505
5888
|
constructor(opts = {}) {
|
|
5506
5889
|
this.opts = opts;
|
|
5507
5890
|
}
|
|
5508
|
-
|
|
5509
|
-
if (!this.
|
|
5510
|
-
|
|
5511
|
-
|
|
5512
|
-
|
|
5513
|
-
|
|
5514
|
-
|
|
5515
|
-
|
|
5516
|
-
"Content-Type": "application/json"
|
|
5517
|
-
},
|
|
5518
|
-
body: JSON.stringify({
|
|
5519
|
-
grant_type: "refresh_token",
|
|
5520
|
-
refresh_token: this.opts.oauth.refresh,
|
|
5521
|
-
client_id: CLIENT_ID
|
|
5522
|
-
})
|
|
5891
|
+
getAuthTransport() {
|
|
5892
|
+
if (!this.authTransport) {
|
|
5893
|
+
const base = new FetchTransport({
|
|
5894
|
+
persistFile: this.opts.httpLogFile,
|
|
5895
|
+
logLevel: "INFO",
|
|
5896
|
+
enableConsoleLog: false,
|
|
5897
|
+
maxFileSize: 5 * 1024 * 1024,
|
|
5898
|
+
captureResponseBody: true
|
|
5523
5899
|
});
|
|
5524
|
-
|
|
5525
|
-
|
|
5526
|
-
|
|
5527
|
-
|
|
5528
|
-
|
|
5529
|
-
|
|
5530
|
-
|
|
5531
|
-
|
|
5532
|
-
|
|
5533
|
-
|
|
5534
|
-
} catch (_error) {
|
|
5535
|
-
return { type: "failed" };
|
|
5536
|
-
}
|
|
5537
|
-
}
|
|
5538
|
-
updateCredentials(result) {
|
|
5539
|
-
if (result.type === "success" && result.access && result.refresh && result.expires) {
|
|
5540
|
-
if (this.opts.oauth) {
|
|
5541
|
-
this.opts.oauth.access = result.access;
|
|
5542
|
-
this.opts.oauth.refresh = result.refresh;
|
|
5543
|
-
this.opts.oauth.expires = result.expires;
|
|
5544
|
-
}
|
|
5545
|
-
this.opts.onTokenUpdate?.({
|
|
5546
|
-
access: result.access,
|
|
5547
|
-
refresh: result.refresh,
|
|
5548
|
-
expires: result.expires
|
|
5900
|
+
this.authTransport = new AnthropicAuthTransport(base, {
|
|
5901
|
+
apiKey: this.opts.apiKey,
|
|
5902
|
+
oauth: this.opts.oauth ? {
|
|
5903
|
+
access: this.opts.oauth.access,
|
|
5904
|
+
refresh: this.opts.oauth.refresh,
|
|
5905
|
+
expires: this.opts.oauth.expires
|
|
5906
|
+
} : void 0,
|
|
5907
|
+
baseUrl: this.opts.baseURL || this.opts.apiUrl,
|
|
5908
|
+
retry: this.opts.retry,
|
|
5909
|
+
onTokenUpdate: this.opts.onTokenUpdate
|
|
5549
5910
|
});
|
|
5550
5911
|
}
|
|
5912
|
+
return this.authTransport;
|
|
5551
5913
|
}
|
|
5552
|
-
|
|
5553
|
-
if (!this.
|
|
5554
|
-
|
|
5555
|
-
const result = await this.refreshPromise;
|
|
5556
|
-
if (result.type === "failed") {
|
|
5557
|
-
throw new Error("Token refresh failed");
|
|
5558
|
-
}
|
|
5559
|
-
return;
|
|
5560
|
-
}
|
|
5561
|
-
this.refreshPromise = this.refreshAccessToken();
|
|
5562
|
-
try {
|
|
5563
|
-
const result = await this.refreshPromise;
|
|
5564
|
-
if (result.type === "success") {
|
|
5565
|
-
this.updateCredentials(result);
|
|
5566
|
-
this.provider = void 0;
|
|
5567
|
-
} else {
|
|
5568
|
-
throw new Error("Token refresh failed");
|
|
5569
|
-
}
|
|
5570
|
-
} finally {
|
|
5571
|
-
this.refreshPromise = null;
|
|
5914
|
+
getTransport() {
|
|
5915
|
+
if (!this.transport) {
|
|
5916
|
+
this.transport = this.getAuthTransport().createRetryTransport();
|
|
5572
5917
|
}
|
|
5918
|
+
return this.transport;
|
|
5573
5919
|
}
|
|
5574
|
-
|
|
5575
|
-
return async (url, init) => {
|
|
5576
|
-
if (init?.headers && this.opts.oauth) {
|
|
5577
|
-
const headers = new Headers(init.headers);
|
|
5578
|
-
headers.delete("x-api-key");
|
|
5579
|
-
headers.set("authorization", `Bearer ${this.opts.oauth.access}`);
|
|
5580
|
-
headers.set("user-agent", "ai-sdk/anthropic/2.0.30 ai-sdk/provider-utils/3.0.12");
|
|
5581
|
-
init = { ...init, headers };
|
|
5582
|
-
}
|
|
5583
|
-
const response = await fetch(url, init);
|
|
5584
|
-
if ((response.status === 401 || response.status === 403) && this.opts.oauth) {
|
|
5585
|
-
await this.ensureValidToken();
|
|
5586
|
-
if (init?.headers) {
|
|
5587
|
-
const headers = new Headers(init.headers);
|
|
5588
|
-
headers.set("authorization", `Bearer ${this.opts.oauth.access}`);
|
|
5589
|
-
init = { ...init, headers };
|
|
5590
|
-
}
|
|
5591
|
-
return fetch(url, init);
|
|
5592
|
-
}
|
|
5593
|
-
return response;
|
|
5594
|
-
};
|
|
5595
|
-
}
|
|
5596
|
-
async getProvider() {
|
|
5920
|
+
getProvider() {
|
|
5597
5921
|
if (this.provider) {
|
|
5598
5922
|
return this.provider;
|
|
5599
5923
|
}
|
|
5924
|
+
const authTransport = this.getAuthTransport();
|
|
5600
5925
|
if (this.opts.oauth) {
|
|
5601
5926
|
this.provider = createAnthropic({
|
|
5602
5927
|
apiKey: "sk-ant-oauth-placeholder",
|
|
5603
|
-
baseURL:
|
|
5928
|
+
baseURL: authTransport.getBaseUrl(),
|
|
5604
5929
|
headers: {
|
|
5605
5930
|
authorization: `Bearer ${this.opts.oauth.access}`,
|
|
5606
5931
|
"anthropic-beta": "oauth-2025-04-20,claude-code-20250219,interleaved-thinking-2025-05-14,fine-grained-tool-streaming-2025-05-14"
|
|
5607
5932
|
},
|
|
5608
|
-
fetch:
|
|
5933
|
+
fetch: authTransport.createFetchFunction()
|
|
5609
5934
|
});
|
|
5610
5935
|
} else {
|
|
5611
5936
|
this.provider = createAnthropic({
|
|
5612
5937
|
apiKey: this.opts.apiKey,
|
|
5613
|
-
baseURL:
|
|
5938
|
+
baseURL: authTransport.getBaseUrl()
|
|
5614
5939
|
});
|
|
5615
5940
|
}
|
|
5616
5941
|
return this.provider;
|
|
5617
5942
|
}
|
|
5618
|
-
|
|
5619
|
-
const provider =
|
|
5943
|
+
getModel(modelName) {
|
|
5944
|
+
const provider = this.getProvider();
|
|
5620
5945
|
return provider(modelName);
|
|
5621
5946
|
}
|
|
5622
5947
|
transformMessages(messages) {
|
|
@@ -5850,7 +6175,7 @@ var AnthropicAISDKLLM = class {
|
|
|
5850
6175
|
}
|
|
5851
6176
|
async generateCompletion(params, signal) {
|
|
5852
6177
|
try {
|
|
5853
|
-
const model =
|
|
6178
|
+
const model = this.getModel(params.model);
|
|
5854
6179
|
const messages = this.transformMessages(params.messages);
|
|
5855
6180
|
const tools = this.transformTools(params.tools);
|
|
5856
6181
|
const toolChoice = tools ? this.transformToolChoice(params.tool_choice) : void 0;
|
|
@@ -5884,7 +6209,7 @@ var AnthropicAISDKLLM = class {
|
|
|
5884
6209
|
}
|
|
5885
6210
|
async streamCompletion(params, handlers = {}, signal) {
|
|
5886
6211
|
let streamError = null;
|
|
5887
|
-
const model =
|
|
6212
|
+
const model = this.getModel(params.model);
|
|
5888
6213
|
const messages = this.transformMessages(params.messages);
|
|
5889
6214
|
const tools = this.transformTools(params.tools);
|
|
5890
6215
|
const toolChoice = tools ? this.transformToolChoice(params.tool_choice) : void 0;
|
|
@@ -5935,45 +6260,17 @@ var AnthropicAISDKLLM = class {
|
|
|
5935
6260
|
}
|
|
5936
6261
|
}
|
|
5937
6262
|
async getModels(signal) {
|
|
5938
|
-
const
|
|
5939
|
-
|
|
5940
|
-
const headers = {
|
|
5941
|
-
"anthropic-version": "2023-06-01",
|
|
5942
|
-
"anthropic-beta": " oauth-2025-04-20,fine-grained-tool-streaming-2025-05-14"
|
|
5943
|
-
};
|
|
5944
|
-
if (this.opts.oauth) {
|
|
5945
|
-
headers.authorization = `Bearer ${this.opts.oauth.access}`;
|
|
5946
|
-
} else if (this.opts.apiKey) {
|
|
5947
|
-
headers["x-api-key"] = this.opts.apiKey;
|
|
5948
|
-
} else {
|
|
6263
|
+
const authTransport = this.getAuthTransport();
|
|
6264
|
+
if (!authTransport.getApiKey() && !authTransport.getOAuth()) {
|
|
5949
6265
|
throw new LLMError("No API key or OAuth credentials provided", 401, false);
|
|
5950
6266
|
}
|
|
5951
6267
|
try {
|
|
5952
|
-
const
|
|
5953
|
-
|
|
5954
|
-
|
|
5955
|
-
|
|
5956
|
-
});
|
|
5957
|
-
if (!response.ok) {
|
|
5958
|
-
if ((response.status === 401 || response.status === 403) && this.opts.oauth) {
|
|
5959
|
-
await this.ensureValidToken();
|
|
5960
|
-
headers.authorization = `Bearer ${this.opts.oauth.access}`;
|
|
5961
|
-
const retryResponse = await fetch(url, {
|
|
5962
|
-
method: "GET",
|
|
5963
|
-
headers,
|
|
5964
|
-
signal
|
|
5965
|
-
});
|
|
5966
|
-
if (!retryResponse.ok) {
|
|
5967
|
-
const text2 = await retryResponse.text();
|
|
5968
|
-
throw new LLMError(text2 || `Failed to fetch models: ${retryResponse.status}`, retryResponse.status);
|
|
5969
|
-
}
|
|
5970
|
-
const data2 = await retryResponse.json();
|
|
5971
|
-
return data2.data.map((model) => normalizeModelInfo("anthropic", model));
|
|
5972
|
-
}
|
|
5973
|
-
const text = await response.text();
|
|
5974
|
-
throw new LLMError(text || `Failed to fetch models: ${response.status}`, response.status);
|
|
6268
|
+
const res = await this.getTransport().get("/models", void 0, signal);
|
|
6269
|
+
if (!res.ok) {
|
|
6270
|
+
const text = await res.text();
|
|
6271
|
+
throw new LLMError(text || `Failed to fetch models: ${res.status}`, res.status);
|
|
5975
6272
|
}
|
|
5976
|
-
const data = await
|
|
6273
|
+
const data = await res.json();
|
|
5977
6274
|
return data.data.map((model) => normalizeModelInfo("anthropic", model));
|
|
5978
6275
|
} catch (error) {
|
|
5979
6276
|
if (error instanceof LLMError) {
|
|
@@ -6050,8 +6347,8 @@ var GenericLLM = class extends BaseLLM {
|
|
|
6050
6347
|
providerName;
|
|
6051
6348
|
customHeaders;
|
|
6052
6349
|
constructor(baseUrl, modelConfig, opts = {}, customHeaders) {
|
|
6053
|
-
const { enablePromptCaching = false, includeUsage = false, providerName = "unknown", ...restOpts } = opts;
|
|
6054
|
-
super(opts.apiUrl || baseUrl, { enablePromptCaching });
|
|
6350
|
+
const { enablePromptCaching = false, includeUsage = false, providerName = "unknown", retry, ...restOpts } = opts;
|
|
6351
|
+
super(opts.apiUrl || baseUrl, { enablePromptCaching, retry });
|
|
6055
6352
|
this.includeUsage = includeUsage;
|
|
6056
6353
|
this.modelConfig = modelConfig;
|
|
6057
6354
|
this.providerName = providerName;
|
|
@@ -6066,7 +6363,7 @@ var GenericLLM = class extends BaseLLM {
|
|
|
6066
6363
|
maxFileSize: 5 * 1024 * 1024,
|
|
6067
6364
|
captureResponseBody: true
|
|
6068
6365
|
});
|
|
6069
|
-
|
|
6366
|
+
const authTransport = createTransport(
|
|
6070
6367
|
base,
|
|
6071
6368
|
this.apiUrl,
|
|
6072
6369
|
this.opts.apiKey,
|
|
@@ -6074,6 +6371,10 @@ var GenericLLM = class extends BaseLLM {
|
|
|
6074
6371
|
this.opts.version,
|
|
6075
6372
|
this.customHeaders
|
|
6076
6373
|
);
|
|
6374
|
+
if (this.retryConfig) {
|
|
6375
|
+
return new RetryTransport(authTransport, this.retryConfig);
|
|
6376
|
+
}
|
|
6377
|
+
return authTransport;
|
|
6077
6378
|
}
|
|
6078
6379
|
async getModels(signal) {
|
|
6079
6380
|
if (this.modelConfig === false) {
|
|
@@ -6464,6 +6765,7 @@ function isValidConfig(value) {
|
|
|
6464
6765
|
}
|
|
6465
6766
|
export {
|
|
6466
6767
|
AGENT_CREATOR_SYSTEM_PROMPT,
|
|
6768
|
+
AbortError,
|
|
6467
6769
|
AgentEventTypes,
|
|
6468
6770
|
AgentFilePersistence,
|
|
6469
6771
|
AgentManager,
|
|
@@ -6476,6 +6778,7 @@ export {
|
|
|
6476
6778
|
ConversationContext,
|
|
6477
6779
|
ConversationStore,
|
|
6478
6780
|
CoreMCPClient,
|
|
6781
|
+
DEFAULT_RETRY_CONFIG,
|
|
6479
6782
|
DefaultDelegationPolicy,
|
|
6480
6783
|
DefaultDelegationResultFormatter,
|
|
6481
6784
|
DefaultDelegationService,
|
|
@@ -6495,6 +6798,7 @@ export {
|
|
|
6495
6798
|
NoopReminders,
|
|
6496
6799
|
PersistedMemory,
|
|
6497
6800
|
PersistingConsoleEventPort,
|
|
6801
|
+
RetryTransport,
|
|
6498
6802
|
RuntimeEnv,
|
|
6499
6803
|
SimpleContextBuilder,
|
|
6500
6804
|
SimpleCost,
|
|
@@ -6533,6 +6837,8 @@ export {
|
|
|
6533
6837
|
isFileReadResult,
|
|
6534
6838
|
isFileReadSuccess,
|
|
6535
6839
|
isJsonResult,
|
|
6840
|
+
isRetryableError,
|
|
6841
|
+
isRetryableStatusCode,
|
|
6536
6842
|
isSuccess,
|
|
6537
6843
|
isSuccessJson,
|
|
6538
6844
|
isSuccessText,
|