@librechat/agents 3.7.18 → 3.7.20
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/cjs/agents/AgentContext.cjs +5 -2
- package/dist/cjs/agents/AgentContext.cjs.map +1 -1
- package/dist/cjs/graphs/Graph.cjs +2 -1
- package/dist/cjs/graphs/Graph.cjs.map +1 -1
- package/dist/cjs/langfuse.cjs +6 -2
- package/dist/cjs/langfuse.cjs.map +1 -1
- package/dist/cjs/llm/invoke.cjs +17 -2
- package/dist/cjs/llm/invoke.cjs.map +1 -1
- package/dist/cjs/llm/openai/index.cjs +110 -24
- package/dist/cjs/llm/openai/index.cjs.map +1 -1
- package/dist/cjs/llm/prepareProviderRequest.cjs +102 -1
- package/dist/cjs/llm/prepareProviderRequest.cjs.map +1 -1
- package/dist/cjs/main.cjs +1 -0
- package/dist/cjs/tools/search/format.cjs +7 -0
- package/dist/cjs/tools/search/format.cjs.map +1 -1
- package/dist/cjs/tools/search/tool.cjs +7 -2
- package/dist/cjs/tools/search/tool.cjs.map +1 -1
- package/dist/esm/agents/AgentContext.mjs +5 -2
- package/dist/esm/agents/AgentContext.mjs.map +1 -1
- package/dist/esm/graphs/Graph.mjs +2 -1
- package/dist/esm/graphs/Graph.mjs.map +1 -1
- package/dist/esm/langfuse.mjs +6 -2
- package/dist/esm/langfuse.mjs.map +1 -1
- package/dist/esm/llm/invoke.mjs +17 -2
- package/dist/esm/llm/invoke.mjs.map +1 -1
- package/dist/esm/llm/openai/index.mjs +110 -25
- package/dist/esm/llm/openai/index.mjs.map +1 -1
- package/dist/esm/llm/prepareProviderRequest.mjs +104 -3
- package/dist/esm/llm/prepareProviderRequest.mjs.map +1 -1
- package/dist/esm/main.mjs +2 -2
- package/dist/esm/tools/search/format.mjs +7 -1
- package/dist/esm/tools/search/format.mjs.map +1 -1
- package/dist/esm/tools/search/tool.mjs +7 -3
- package/dist/esm/tools/search/tool.mjs.map +1 -1
- package/dist/types/agents/AgentContext.d.ts +4 -1
- package/dist/types/langfuse.d.ts +5 -1
- package/dist/types/llm/openai/index.d.ts +11 -1
- package/dist/types/llm/prepareProviderRequest.d.ts +1 -1
- package/dist/types/tools/search/format.d.ts +2 -1
- package/dist/types/tools/search/tool.d.ts +1 -0
- package/dist/types/types/graph.d.ts +2 -0
- package/dist/types/types/llm.d.ts +23 -0
- package/package.json +2 -1
- package/src/agents/AgentContext.ts +7 -0
- package/src/graphs/Graph.ts +2 -1
- package/src/langfuse.ts +12 -0
- package/src/llm/invoke.ts +23 -2
- package/src/llm/openai/index.ts +281 -27
- package/src/llm/prepareProviderRequest.ts +257 -6
- package/src/tools/search/format.ts +15 -1
- package/src/tools/search/tool.ts +13 -3
- package/src/types/graph.ts +2 -0
- package/src/types/llm.ts +23 -0
|
@@ -1,5 +1,10 @@
|
|
|
1
|
+
import { Buffer } from 'node:buffer';
|
|
2
|
+
import type {
|
|
3
|
+
BaseMessage,
|
|
4
|
+
Data,
|
|
5
|
+
MessageContentComplex,
|
|
6
|
+
} from '@langchain/core/messages';
|
|
1
7
|
import type { RunnableConfig } from '@langchain/core/runnables';
|
|
2
|
-
import type { BaseMessage } from '@langchain/core/messages';
|
|
3
8
|
import type { ToolOutputReferenceRegistry } from '@/tools/toolOutputReferences';
|
|
4
9
|
import type * as t from '@/types';
|
|
5
10
|
import {
|
|
@@ -20,14 +25,60 @@ import {
|
|
|
20
25
|
import {
|
|
21
26
|
stripAnthropicCacheControl,
|
|
22
27
|
stripBedrockCacheControl,
|
|
28
|
+
cloneMessage,
|
|
23
29
|
} from '@/messages/cache';
|
|
30
|
+
import {
|
|
31
|
+
isAnthropicLike,
|
|
32
|
+
isGoogleLike,
|
|
33
|
+
isOpenAILike,
|
|
34
|
+
} from '@/utils/llm';
|
|
24
35
|
import { annotateMessagesForLLM } from '@/tools/toolOutputReferences';
|
|
25
36
|
import { providerRequiresStrictAlternation } from '@/llm/providers';
|
|
26
|
-
import { isAnthropicLike, isOpenAILike } from '@/utils/llm';
|
|
27
37
|
import { getProviderFamily } from '@/llm/providerRegistry';
|
|
28
38
|
import { Providers } from '@/common';
|
|
29
39
|
|
|
30
40
|
const preparedProviderRequestBrand = Symbol('PreparedProviderRequest');
|
|
41
|
+
const OMITTED_ATTACHMENT_TEXT =
|
|
42
|
+
'[Attachment omitted because its binary format is unsupported by this provider.]';
|
|
43
|
+
|
|
44
|
+
const BEDROCK_DOCUMENT_MIME_TYPES: Readonly<Partial<Record<string, string>>> = {
|
|
45
|
+
csv: 'text/csv',
|
|
46
|
+
doc: 'application/msword',
|
|
47
|
+
docx: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
|
48
|
+
html: 'text/html',
|
|
49
|
+
md: 'text/markdown',
|
|
50
|
+
pdf: 'application/pdf',
|
|
51
|
+
txt: 'text/plain',
|
|
52
|
+
xls: 'application/vnd.ms-excel',
|
|
53
|
+
xlsx: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
interface SerializedBuffer {
|
|
57
|
+
type: 'Buffer';
|
|
58
|
+
data: number[];
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
interface BedrockDocumentBlock {
|
|
62
|
+
type: 'document';
|
|
63
|
+
document: {
|
|
64
|
+
name: string;
|
|
65
|
+
format: string;
|
|
66
|
+
source: {
|
|
67
|
+
bytes: Uint8Array | SerializedBuffer;
|
|
68
|
+
};
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
type StandardBase64FileBlock = Data.StandardFileBlock & {
|
|
73
|
+
source_type: 'base64';
|
|
74
|
+
mime_type: string;
|
|
75
|
+
data: string;
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
type ProviderContentBlock =
|
|
79
|
+
| MessageContentComplex
|
|
80
|
+
| BedrockDocumentBlock
|
|
81
|
+
| StandardBase64FileBlock;
|
|
31
82
|
|
|
32
83
|
export type ProviderMessageProjectionMode =
|
|
33
84
|
| 'chat-messages'
|
|
@@ -159,16 +210,216 @@ interface ProjectMessagesForProviderParams {
|
|
|
159
210
|
callOptions?: unknown;
|
|
160
211
|
}
|
|
161
212
|
|
|
213
|
+
function isSerializedBuffer(value: object): value is SerializedBuffer {
|
|
214
|
+
return (
|
|
215
|
+
'type' in value &&
|
|
216
|
+
value.type === 'Buffer' &&
|
|
217
|
+
'data' in value &&
|
|
218
|
+
Array.isArray(value.data)
|
|
219
|
+
);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
function isBedrockDocumentBlock(
|
|
223
|
+
block: ProviderContentBlock
|
|
224
|
+
): block is BedrockDocumentBlock {
|
|
225
|
+
if (block.type !== 'document' || !('document' in block)) {
|
|
226
|
+
return false;
|
|
227
|
+
}
|
|
228
|
+
const document = block.document;
|
|
229
|
+
if (typeof document !== 'object' || document == null) {
|
|
230
|
+
return false;
|
|
231
|
+
}
|
|
232
|
+
if (
|
|
233
|
+
!('name' in document) ||
|
|
234
|
+
typeof document.name !== 'string' ||
|
|
235
|
+
!('format' in document) ||
|
|
236
|
+
typeof document.format !== 'string' ||
|
|
237
|
+
!('source' in document) ||
|
|
238
|
+
typeof document.source !== 'object' ||
|
|
239
|
+
document.source == null ||
|
|
240
|
+
!('bytes' in document.source)
|
|
241
|
+
) {
|
|
242
|
+
return false;
|
|
243
|
+
}
|
|
244
|
+
const bytes = document.source.bytes;
|
|
245
|
+
return (
|
|
246
|
+
bytes instanceof Uint8Array ||
|
|
247
|
+
(typeof bytes === 'object' && bytes != null && isSerializedBuffer(bytes))
|
|
248
|
+
);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
function toStandardFileBlock(
|
|
252
|
+
block: BedrockDocumentBlock
|
|
253
|
+
): StandardBase64FileBlock | undefined {
|
|
254
|
+
const mimeType = BEDROCK_DOCUMENT_MIME_TYPES[block.document.format];
|
|
255
|
+
if (mimeType == null) {
|
|
256
|
+
return undefined;
|
|
257
|
+
}
|
|
258
|
+
const source = block.document.source.bytes;
|
|
259
|
+
const bytes = source instanceof Uint8Array ? source : source.data;
|
|
260
|
+
return {
|
|
261
|
+
type: 'file',
|
|
262
|
+
source_type: 'base64',
|
|
263
|
+
mime_type: mimeType,
|
|
264
|
+
data: Buffer.from(bytes).toString('base64'),
|
|
265
|
+
metadata: { name: block.document.name },
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
function isStandardFileBlock(
|
|
270
|
+
block: ProviderContentBlock
|
|
271
|
+
): block is StandardBase64FileBlock {
|
|
272
|
+
return (
|
|
273
|
+
block.type === 'file' &&
|
|
274
|
+
'source_type' in block &&
|
|
275
|
+
block.source_type === 'base64' &&
|
|
276
|
+
'mime_type' in block &&
|
|
277
|
+
typeof block.mime_type === 'string' &&
|
|
278
|
+
'data' in block &&
|
|
279
|
+
typeof block.data === 'string'
|
|
280
|
+
);
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
function shouldRetainStandardFile(
|
|
284
|
+
provider: t.ProviderName,
|
|
285
|
+
mimeType: string
|
|
286
|
+
): boolean {
|
|
287
|
+
const normalizedMimeType = mimeType.split(';', 1)[0].trim().toLowerCase();
|
|
288
|
+
if (
|
|
289
|
+
provider === Providers.ANTHROPIC ||
|
|
290
|
+
getProviderFamily(provider) === 'anthropic'
|
|
291
|
+
) {
|
|
292
|
+
return (
|
|
293
|
+
normalizedMimeType === 'application/pdf' ||
|
|
294
|
+
normalizedMimeType === 'image/jpeg' ||
|
|
295
|
+
normalizedMimeType === 'image/png' ||
|
|
296
|
+
normalizedMimeType === 'image/gif' ||
|
|
297
|
+
normalizedMimeType === 'image/webp'
|
|
298
|
+
);
|
|
299
|
+
}
|
|
300
|
+
if (isOpenAILike(provider)) {
|
|
301
|
+
return normalizedMimeType === 'application/pdf';
|
|
302
|
+
}
|
|
303
|
+
return true;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
function canProjectBedrockDocument(
|
|
307
|
+
provider: t.ProviderName,
|
|
308
|
+
mimeType: string
|
|
309
|
+
): boolean {
|
|
310
|
+
if (isGoogleLike(provider)) {
|
|
311
|
+
return true;
|
|
312
|
+
}
|
|
313
|
+
if (
|
|
314
|
+
provider === Providers.ANTHROPIC ||
|
|
315
|
+
getProviderFamily(provider) === 'anthropic' ||
|
|
316
|
+
isOpenAILike(provider)
|
|
317
|
+
) {
|
|
318
|
+
return mimeType === 'application/pdf';
|
|
319
|
+
}
|
|
320
|
+
return false;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
function isBlankTextBlock(block: ProviderContentBlock): boolean {
|
|
324
|
+
return (
|
|
325
|
+
block.type === 'text' &&
|
|
326
|
+
'text' in block &&
|
|
327
|
+
typeof block.text === 'string' &&
|
|
328
|
+
block.text.trim() === ''
|
|
329
|
+
);
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
function copyUsableContentPrefix(
|
|
333
|
+
sourceContent: ProviderContentBlock[],
|
|
334
|
+
end: number
|
|
335
|
+
): ProviderContentBlock[] {
|
|
336
|
+
const content: ProviderContentBlock[] = [];
|
|
337
|
+
for (let index = 0; index < end; index++) {
|
|
338
|
+
const block = sourceContent[index];
|
|
339
|
+
if (!isBlankTextBlock(block)) {
|
|
340
|
+
content.push(block);
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
return content;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
/** Reprojects persisted provider-native attachments without changing history. */
|
|
347
|
+
function projectAttachmentsForProvider(
|
|
348
|
+
messages: BaseMessage[],
|
|
349
|
+
provider: t.ProviderName
|
|
350
|
+
): BaseMessage[] {
|
|
351
|
+
if (
|
|
352
|
+
provider === Providers.BEDROCK ||
|
|
353
|
+
getProviderFamily(provider) === 'bedrock'
|
|
354
|
+
) {
|
|
355
|
+
return messages;
|
|
356
|
+
}
|
|
357
|
+
let projected: BaseMessage[] | undefined;
|
|
358
|
+
for (let messageIndex = 0; messageIndex < messages.length; messageIndex++) {
|
|
359
|
+
const message = messages[messageIndex];
|
|
360
|
+
if (!Array.isArray(message.content)) {
|
|
361
|
+
continue;
|
|
362
|
+
}
|
|
363
|
+
const sourceContent = message.content as ProviderContentBlock[];
|
|
364
|
+
let content: ProviderContentBlock[] | undefined;
|
|
365
|
+
for (let blockIndex = 0; blockIndex < sourceContent.length; blockIndex++) {
|
|
366
|
+
const block = sourceContent[blockIndex];
|
|
367
|
+
if (isStandardFileBlock(block)) {
|
|
368
|
+
if (shouldRetainStandardFile(provider, block.mime_type)) {
|
|
369
|
+
content?.push(block);
|
|
370
|
+
continue;
|
|
371
|
+
}
|
|
372
|
+
content ??= copyUsableContentPrefix(sourceContent, blockIndex);
|
|
373
|
+
continue;
|
|
374
|
+
}
|
|
375
|
+
if (!isBedrockDocumentBlock(block)) {
|
|
376
|
+
if (content != null && !isBlankTextBlock(block)) {
|
|
377
|
+
content.push(block);
|
|
378
|
+
}
|
|
379
|
+
continue;
|
|
380
|
+
}
|
|
381
|
+
content ??= copyUsableContentPrefix(sourceContent, blockIndex);
|
|
382
|
+
const mimeType = BEDROCK_DOCUMENT_MIME_TYPES[block.document.format];
|
|
383
|
+
if (
|
|
384
|
+
mimeType == null ||
|
|
385
|
+
!canProjectBedrockDocument(provider, mimeType)
|
|
386
|
+
) {
|
|
387
|
+
continue;
|
|
388
|
+
}
|
|
389
|
+
const standardFile = toStandardFileBlock(block);
|
|
390
|
+
if (standardFile == null) {
|
|
391
|
+
continue;
|
|
392
|
+
}
|
|
393
|
+
content.push(standardFile);
|
|
394
|
+
}
|
|
395
|
+
if (content == null) {
|
|
396
|
+
continue;
|
|
397
|
+
}
|
|
398
|
+
if (content.length === 0) {
|
|
399
|
+
content.push({ type: 'text', text: OMITTED_ATTACHMENT_TEXT });
|
|
400
|
+
}
|
|
401
|
+
projected ??= [...messages];
|
|
402
|
+
projected[messageIndex] = cloneMessage(
|
|
403
|
+
message,
|
|
404
|
+
content as MessageContentComplex[]
|
|
405
|
+
);
|
|
406
|
+
}
|
|
407
|
+
return projected ?? messages;
|
|
408
|
+
}
|
|
409
|
+
|
|
162
410
|
function projectMessagesForProviderMode(
|
|
163
411
|
{ messages, provider, maxToolResultChars }: ProjectMessagesForProviderParams,
|
|
164
412
|
projectionMode: ProviderMessageProjectionMode
|
|
165
413
|
): BaseMessage[] {
|
|
166
414
|
const providerFamily = getProviderFamily(provider);
|
|
167
415
|
const nativeOpenAIResponses = projectionMode === 'openai-responses';
|
|
168
|
-
const providerInputMessages =
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
416
|
+
const providerInputMessages = projectAttachmentsForProvider(
|
|
417
|
+
projectToolStreamContentForProvider(
|
|
418
|
+
messages,
|
|
419
|
+
nativeOpenAIResponses ? 'native' : 'fallback',
|
|
420
|
+
maxToolResultChars
|
|
421
|
+
),
|
|
422
|
+
provider
|
|
172
423
|
);
|
|
173
424
|
if (nativeOpenAIResponses) {
|
|
174
425
|
return projectOpenAIResponsesToolMessageContent(
|
|
@@ -11,6 +11,9 @@ const DEFAULT_MAX_LLM_OUTPUT_CHARS = 50000;
|
|
|
11
11
|
* this we drop it whole rather than emit a useless sliver. */
|
|
12
12
|
const MIN_PARTIAL_HIGHLIGHT_CHARS = 200;
|
|
13
13
|
|
|
14
|
+
export const MISSING_SEARCH_RESULT_DATA_ERROR =
|
|
15
|
+
'Search provider returned no result data';
|
|
16
|
+
|
|
14
17
|
/** Resolves the per-search highlight budget from config, the
|
|
15
18
|
* `SEARCH_MAX_LLM_OUTPUT_CHARS` env var, or the default (50,000 chars). */
|
|
16
19
|
export function resolveMaxLLMOutputChars(maxOutputChars?: number): number {
|
|
@@ -219,9 +222,16 @@ function formatSource(
|
|
|
219
222
|
|
|
220
223
|
export function formatResultsForLLM(
|
|
221
224
|
turn: number,
|
|
222
|
-
results
|
|
225
|
+
results?: t.SearchResultData | null,
|
|
223
226
|
maxOutputChars?: number
|
|
224
227
|
): { output: string; references: t.ResultReference[] } {
|
|
228
|
+
if (results == null) {
|
|
229
|
+
return {
|
|
230
|
+
output: `Search failed: ${MISSING_SEARCH_RESULT_DATA_ERROR}`,
|
|
231
|
+
references: [],
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
|
|
225
235
|
/** Bound highlight content to the per-search budget before formatting */
|
|
226
236
|
const trimmedHighlights = trimHighlightsToBudget(
|
|
227
237
|
results,
|
|
@@ -239,6 +249,10 @@ export function formatResultsForLLM(
|
|
|
239
249
|
|
|
240
250
|
const references: t.ResultReference[] = [];
|
|
241
251
|
|
|
252
|
+
if (results.error != null && results.error !== '') {
|
|
253
|
+
outputLines.push(`Search failed: ${results.error}`);
|
|
254
|
+
}
|
|
255
|
+
|
|
242
256
|
// Organic (web) results
|
|
243
257
|
if (results.organic?.length != null && results.organic.length > 0) {
|
|
244
258
|
addSection(`Web Results, Turn ${turn}`);
|
package/src/tools/search/tool.ts
CHANGED
|
@@ -21,7 +21,10 @@ import { INTENT_PROPERTY } from '@/tools/intentArg';
|
|
|
21
21
|
import { createCrwScraper } from './crw-scraper';
|
|
22
22
|
import { expandHighlights } from './highlights';
|
|
23
23
|
import { createSearchMetrics } from './metrics';
|
|
24
|
-
import {
|
|
24
|
+
import {
|
|
25
|
+
formatResultsForLLM,
|
|
26
|
+
MISSING_SEARCH_RESULT_DATA_ERROR,
|
|
27
|
+
} from './format';
|
|
25
28
|
import { createDefaultLogger } from './utils';
|
|
26
29
|
import { createReranker } from './rerankers';
|
|
27
30
|
import { Constants } from '@/common';
|
|
@@ -66,6 +69,12 @@ export function resolveSearchOutcome(
|
|
|
66
69
|
return `Found ${count} result${count === 1 ? '' : 's'} for "${query}"`;
|
|
67
70
|
}
|
|
68
71
|
|
|
72
|
+
export function normalizeSearchResultData(
|
|
73
|
+
result: t.SearchResultData | null | undefined
|
|
74
|
+
): t.SearchResultData {
|
|
75
|
+
return result ?? { error: MISSING_SEARCH_RESULT_DATA_ERROR };
|
|
76
|
+
}
|
|
77
|
+
|
|
69
78
|
/** Distinct rows across the main search's two collections. SearXNG derives
|
|
70
79
|
* both from one result array — a row matching its news heuristic lands in
|
|
71
80
|
* `organic` and `topStories` alike — so summing the lengths would report
|
|
@@ -431,12 +440,13 @@ function createTool({
|
|
|
431
440
|
}),
|
|
432
441
|
});
|
|
433
442
|
const turn = runnableConfig.toolCall?.turn ?? 0;
|
|
443
|
+
const resultData = normalizeSearchResultData(searchResult);
|
|
434
444
|
const { output, references } = formatResultsForLLM(
|
|
435
445
|
turn,
|
|
436
|
-
|
|
446
|
+
resultData,
|
|
437
447
|
maxOutputChars
|
|
438
448
|
);
|
|
439
|
-
const data: t.SearchResultData = { turn, ...
|
|
449
|
+
const data: t.SearchResultData = { turn, ...resultData, references };
|
|
440
450
|
const outcome = resolveSearchOutcome(data, query);
|
|
441
451
|
return [
|
|
442
452
|
output,
|
package/src/types/graph.ts
CHANGED
|
@@ -853,6 +853,8 @@ export interface LangfuseConfig {
|
|
|
853
853
|
|
|
854
854
|
interface AgentInputFields {
|
|
855
855
|
agentId: string;
|
|
856
|
+
/** Logical endpoint selected by the host before provider resolution. */
|
|
857
|
+
endpoint?: string;
|
|
856
858
|
/**
|
|
857
859
|
* Partition key for transient code-session ids and file refs. Agents with
|
|
858
860
|
* the same key share those refs; different execution profiles/scopes must
|
package/src/types/llm.ts
CHANGED
|
@@ -81,6 +81,29 @@ export type GoogleThinkingConfig = {
|
|
|
81
81
|
export type ManagedRequestOptions = {
|
|
82
82
|
promptCacheExplicit?: boolean;
|
|
83
83
|
safety_identifier?: string;
|
|
84
|
+
/**
|
|
85
|
+
* Declares that this client talks to the first-party OpenAI or Azure surface.
|
|
86
|
+
* Gates the model-specific request *shaping* documented only for it —
|
|
87
|
+
* currently GPT-6 Astra's rejected sampling and logprob parameters, its
|
|
88
|
+
* unsupported reasoning efforts, and the encrypted reasoning it supports —
|
|
89
|
+
* and defaults to off.
|
|
90
|
+
*
|
|
91
|
+
* Shaping only. Which API serves the turn is not decided here: GPT-6 Astra
|
|
92
|
+
* serves tool calls only from the Responses API, and a caller wanting them
|
|
93
|
+
* must select it with `useResponsesApi`, alongside the rest of the request
|
|
94
|
+
* shaping that depends on which API is in use.
|
|
95
|
+
*
|
|
96
|
+
* The shaping runs inside this SDK's own request delegates. A caller that
|
|
97
|
+
* supplies its own `completions` or `responses` delegate replaces that
|
|
98
|
+
* construction and owns the request shaping for it — this flag cannot reach
|
|
99
|
+
* inside a delegate it did not build.
|
|
100
|
+
*
|
|
101
|
+
* Declared rather than inferred from a base URL: only the caller knows
|
|
102
|
+
* whether a URL is a faithful first-party route, a gateway, or a proxy with
|
|
103
|
+
* its own semantics, and every gate it controls removes capability, so
|
|
104
|
+
* guessing wrong silently degrades an endpoint the SDK cannot see.
|
|
105
|
+
*/
|
|
106
|
+
firstPartyEndpoint?: boolean;
|
|
84
107
|
};
|
|
85
108
|
/**
|
|
86
109
|
* Adaptive stream-smoothing configuration shared by every provider client.
|