@librechat/agents 3.7.18 → 3.7.19
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/prepareProviderRequest.cjs +102 -1
- package/dist/cjs/llm/prepareProviderRequest.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/prepareProviderRequest.mjs +104 -3
- package/dist/esm/llm/prepareProviderRequest.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/prepareProviderRequest.d.ts +1 -1
- package/dist/types/types/graph.d.ts +2 -0
- package/package.json +1 -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/prepareProviderRequest.ts +257 -6
- package/src/types/graph.ts +2 -0
package/dist/types/langfuse.d.ts
CHANGED
|
@@ -44,7 +44,7 @@ type LangfuseAttributeParams = AgentLangfuseHandlerParams & {
|
|
|
44
44
|
};
|
|
45
45
|
export declare function isExplicitLangfuseConfig(langfuse?: t.LangfuseConfig): boolean;
|
|
46
46
|
export declare function createLibreChatTraceAttributes(attributes: LangfuseConfigTraceAttributes): LangfuseTraceAttributes;
|
|
47
|
-
export declare function createLangfuseTraceMetadata({ messageId, parentMessageId, agentId, agentName, rootAgentId, rootAgentName, activeAgentId, activeAgentName, }: {
|
|
47
|
+
export declare function createLangfuseTraceMetadata({ messageId, parentMessageId, agentId, agentName, rootAgentId, rootAgentName, activeAgentId, activeAgentName, endpoint, model, provider, resolvedProvider, }: {
|
|
48
48
|
messageId?: unknown;
|
|
49
49
|
parentMessageId?: unknown;
|
|
50
50
|
agentId?: unknown;
|
|
@@ -53,6 +53,10 @@ export declare function createLangfuseTraceMetadata({ messageId, parentMessageId
|
|
|
53
53
|
rootAgentName?: unknown;
|
|
54
54
|
activeAgentId?: unknown;
|
|
55
55
|
activeAgentName?: unknown;
|
|
56
|
+
endpoint?: unknown;
|
|
57
|
+
model?: unknown;
|
|
58
|
+
provider?: unknown;
|
|
59
|
+
resolvedProvider?: unknown;
|
|
56
60
|
}): LangfuseTraceMetadata;
|
|
57
61
|
export declare function getLangfuseTraceName(traceMetadata?: LangfuseTraceMetadata, fallback?: string): string;
|
|
58
62
|
export declare function shouldCreateLangfuseHandler(langfuse?: t.LangfuseConfig): boolean;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { RunnableConfig } from '@langchain/core/runnables';
|
|
2
1
|
import type { BaseMessage } from '@langchain/core/messages';
|
|
2
|
+
import type { RunnableConfig } from '@langchain/core/runnables';
|
|
3
3
|
import type { ToolOutputReferenceRegistry } from '@/tools/toolOutputReferences';
|
|
4
4
|
import type * as t from '@/types';
|
|
5
5
|
declare const preparedProviderRequestBrand: unique symbol;
|
|
@@ -672,6 +672,8 @@ export interface LangfuseConfig {
|
|
|
672
672
|
}
|
|
673
673
|
interface AgentInputFields {
|
|
674
674
|
agentId: string;
|
|
675
|
+
/** Logical endpoint selected by the host before provider resolution. */
|
|
676
|
+
endpoint?: string;
|
|
675
677
|
/**
|
|
676
678
|
* Partition key for transient code-session ids and file refs. Agents with
|
|
677
679
|
* the same key share those refs; different execution profiles/scopes must
|
package/package.json
CHANGED
|
@@ -104,6 +104,7 @@ export class AgentContext {
|
|
|
104
104
|
): AgentContext {
|
|
105
105
|
const {
|
|
106
106
|
agentId,
|
|
107
|
+
endpoint,
|
|
107
108
|
codeSessionKey,
|
|
108
109
|
name,
|
|
109
110
|
provider,
|
|
@@ -135,6 +136,7 @@ export class AgentContext {
|
|
|
135
136
|
|
|
136
137
|
const agentContext = new AgentContext({
|
|
137
138
|
agentId,
|
|
139
|
+
endpoint,
|
|
138
140
|
codeSessionKey,
|
|
139
141
|
name: name ?? agentId,
|
|
140
142
|
provider,
|
|
@@ -219,6 +221,8 @@ export class AgentContext {
|
|
|
219
221
|
|
|
220
222
|
/** Agent identifier */
|
|
221
223
|
agentId: string;
|
|
224
|
+
/** Logical endpoint selected by the host before provider resolution. */
|
|
225
|
+
endpoint: string;
|
|
222
226
|
/** Partition for this agent's transient code session and file refs. */
|
|
223
227
|
codeSessionKey?: string;
|
|
224
228
|
/** Human-readable name for this agent (used in handoff context). Falls back to agentId if not provided. */
|
|
@@ -454,6 +458,7 @@ export class AgentContext {
|
|
|
454
458
|
|
|
455
459
|
constructor({
|
|
456
460
|
agentId,
|
|
461
|
+
endpoint,
|
|
457
462
|
codeSessionKey,
|
|
458
463
|
name,
|
|
459
464
|
provider,
|
|
@@ -481,6 +486,7 @@ export class AgentContext {
|
|
|
481
486
|
maxToolResultChars,
|
|
482
487
|
}: {
|
|
483
488
|
agentId: string;
|
|
489
|
+
endpoint?: string;
|
|
484
490
|
codeSessionKey?: string;
|
|
485
491
|
name?: string;
|
|
486
492
|
provider: t.ProviderName;
|
|
@@ -508,6 +514,7 @@ export class AgentContext {
|
|
|
508
514
|
maxToolResultChars?: number;
|
|
509
515
|
}) {
|
|
510
516
|
this.agentId = agentId;
|
|
517
|
+
this.endpoint = endpoint ?? provider;
|
|
511
518
|
this.codeSessionKey = codeSessionKey;
|
|
512
519
|
this.name = name;
|
|
513
520
|
this.provider = provider;
|
package/src/graphs/Graph.ts
CHANGED
|
@@ -151,6 +151,7 @@ import { shouldTraceToolNodeForLangfuse } from '@/langfuseToolOutputTracing';
|
|
|
151
151
|
import { createLocalCodingToolBundle } from '@/tools/local/LocalCodingTools';
|
|
152
152
|
import { SUBAGENT_REPLAY_CONTROLLER } from '@/tools/subagent/SubagentReplay';
|
|
153
153
|
import { applyGraphRuntimeConfig } from '@/graphs/applyGraphRuntimeConfig';
|
|
154
|
+
import { isFadingTier, isInformativeFadingTier } from '@/messages/fading';
|
|
154
155
|
import { createContextPressureMeter } from '@/llm/contextPressureMeter';
|
|
155
156
|
import { safeDispatchCustomEvent, emitAgentLog } from '@/utils/events';
|
|
156
157
|
import { prepareProviderRequest } from '@/llm/prepareProviderRequest';
|
|
@@ -163,7 +164,6 @@ import { initializeLangfuseTracing } from '@/instrumentation';
|
|
|
163
164
|
import { shouldTriggerSummarization } from '@/summarization';
|
|
164
165
|
import { isRunStepResumeState } from '@/tools/runStepResume';
|
|
165
166
|
import { resolveLocalToolsForBinding } from '@/tools/local';
|
|
166
|
-
import { isFadingTier, isInformativeFadingTier } from '@/messages/fading';
|
|
167
167
|
import { createSummarizeNode } from '@/summarization/node';
|
|
168
168
|
import { getTruncationStopReason } from '@/llm/truncation';
|
|
169
169
|
import { messagesStateReducer } from '@/messages/reducer';
|
|
@@ -3992,6 +3992,7 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
|
|
|
3992
3992
|
rootAgentName: this.agentContexts.get(this.defaultAgentId)?.name,
|
|
3993
3993
|
activeAgentId: agentId,
|
|
3994
3994
|
activeAgentName: agentContext.name,
|
|
3995
|
+
endpoint: agentContext.endpoint,
|
|
3995
3996
|
});
|
|
3996
3997
|
let langfuseHandler: CallbackEntry | undefined;
|
|
3997
3998
|
let invokeConfig = {
|
package/src/langfuse.ts
CHANGED
|
@@ -840,6 +840,10 @@ export function createLangfuseTraceMetadata({
|
|
|
840
840
|
rootAgentName,
|
|
841
841
|
activeAgentId,
|
|
842
842
|
activeAgentName,
|
|
843
|
+
endpoint,
|
|
844
|
+
model,
|
|
845
|
+
provider,
|
|
846
|
+
resolvedProvider,
|
|
843
847
|
}: {
|
|
844
848
|
messageId?: unknown;
|
|
845
849
|
parentMessageId?: unknown;
|
|
@@ -849,6 +853,10 @@ export function createLangfuseTraceMetadata({
|
|
|
849
853
|
rootAgentName?: unknown;
|
|
850
854
|
activeAgentId?: unknown;
|
|
851
855
|
activeAgentName?: unknown;
|
|
856
|
+
endpoint?: unknown;
|
|
857
|
+
model?: unknown;
|
|
858
|
+
provider?: unknown;
|
|
859
|
+
resolvedProvider?: unknown;
|
|
852
860
|
}): LangfuseTraceMetadata {
|
|
853
861
|
return createTraceMetadata({
|
|
854
862
|
messageId,
|
|
@@ -859,6 +867,10 @@ export function createLangfuseTraceMetadata({
|
|
|
859
867
|
rootAgentName,
|
|
860
868
|
activeAgentId,
|
|
861
869
|
activeAgentName,
|
|
870
|
+
endpoint,
|
|
871
|
+
model,
|
|
872
|
+
provider,
|
|
873
|
+
resolvedProvider,
|
|
862
874
|
});
|
|
863
875
|
}
|
|
864
876
|
|
package/src/llm/invoke.ts
CHANGED
|
@@ -692,11 +692,32 @@ export async function attemptInvoke(
|
|
|
692
692
|
config?: RunnableConfig
|
|
693
693
|
): Promise<Partial<t.BaseGraphState>> {
|
|
694
694
|
const provider = resolveAttemptProvider(params);
|
|
695
|
-
const
|
|
695
|
+
const providerStampedConfig: RunnableConfig = {
|
|
696
696
|
...config,
|
|
697
697
|
metadata: {
|
|
698
698
|
...(config?.metadata ?? {}),
|
|
699
699
|
[Constants.INVOKED_PROVIDER]: provider,
|
|
700
|
+
provider,
|
|
701
|
+
resolvedProvider: provider,
|
|
702
|
+
},
|
|
703
|
+
};
|
|
704
|
+
const request = resolveAttemptRequest(params, providerStampedConfig);
|
|
705
|
+
const configuredModel = providerStampedConfig.metadata?.[
|
|
706
|
+
Constants.INVOKED_MODEL
|
|
707
|
+
];
|
|
708
|
+
const modelId =
|
|
709
|
+
request.modelId ??
|
|
710
|
+
(typeof configuredModel === 'string' ? configuredModel : undefined);
|
|
711
|
+
const stampedConfig: RunnableConfig = {
|
|
712
|
+
...providerStampedConfig,
|
|
713
|
+
metadata: {
|
|
714
|
+
...providerStampedConfig.metadata,
|
|
715
|
+
...(modelId == null
|
|
716
|
+
? {}
|
|
717
|
+
: {
|
|
718
|
+
[Constants.INVOKED_MODEL]: modelId,
|
|
719
|
+
model: modelId,
|
|
720
|
+
}),
|
|
700
721
|
/**
|
|
701
722
|
* One `attemptInvoke` call is one model attempt; primary, fallback,
|
|
702
723
|
* and retry attempts within a node otherwise share the same langgraph
|
|
@@ -727,7 +748,7 @@ export async function attemptInvoke(
|
|
|
727
748
|
try {
|
|
728
749
|
return await attemptInvokeBody(
|
|
729
750
|
{
|
|
730
|
-
request
|
|
751
|
+
request,
|
|
731
752
|
context: params.context,
|
|
732
753
|
onChunk: params.onChunk,
|
|
733
754
|
preemptAgentId: params.preemptAgentId,
|
|
@@ -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(
|
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
|