@librechat/agents 3.7.22 → 3.8.1
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 +13 -3
- package/dist/cjs/agents/AgentContext.cjs.map +1 -1
- package/dist/cjs/graphs/Graph.cjs +174 -53
- package/dist/cjs/graphs/Graph.cjs.map +1 -1
- package/dist/cjs/graphs/MultiAgentGraph.cjs +15 -5
- package/dist/cjs/graphs/MultiAgentGraph.cjs.map +1 -1
- package/dist/cjs/langfuse.cjs +48 -2
- package/dist/cjs/langfuse.cjs.map +1 -1
- package/dist/cjs/langfuseToolOutputTracing.cjs +42 -0
- package/dist/cjs/langfuseToolOutputTracing.cjs.map +1 -1
- package/dist/cjs/langfuseTraceShaping.cjs +7 -1
- package/dist/cjs/langfuseTraceShaping.cjs.map +1 -1
- package/dist/cjs/llm/anthropic/utils/message_inputs.cjs +5 -9
- package/dist/cjs/llm/anthropic/utils/message_inputs.cjs.map +1 -1
- package/dist/cjs/llm/bedrock/utils/message_inputs.cjs +2 -7
- package/dist/cjs/llm/bedrock/utils/message_inputs.cjs.map +1 -1
- package/dist/cjs/llm/contextPressureMeter.cjs +51 -10
- package/dist/cjs/llm/contextPressureMeter.cjs.map +1 -1
- package/dist/cjs/llm/init.cjs +1 -1
- package/dist/cjs/llm/invoke.cjs +2 -2
- package/dist/cjs/llm/openai/index.cjs +4 -3
- package/dist/cjs/llm/openai/index.cjs.map +1 -1
- package/dist/cjs/llm/openai/utils/index.cjs +5 -4
- package/dist/cjs/llm/openai/utils/index.cjs.map +1 -1
- package/dist/cjs/llm/preempt.cjs +3 -2
- package/dist/cjs/llm/preempt.cjs.map +1 -1
- package/dist/cjs/llm/prepareProviderRequest.cjs +9 -7
- package/dist/cjs/llm/prepareProviderRequest.cjs.map +1 -1
- package/dist/cjs/llm/providers.cjs +1 -1
- package/dist/cjs/main.cjs +11 -5
- package/dist/cjs/messages/alternation.cjs +1 -5
- package/dist/cjs/messages/alternation.cjs.map +1 -1
- package/dist/cjs/messages/budget.cjs +206 -7
- package/dist/cjs/messages/budget.cjs.map +1 -1
- package/dist/cjs/messages/cache.cjs +3 -9
- package/dist/cjs/messages/cache.cjs.map +1 -1
- package/dist/cjs/messages/core.cjs +25 -37
- package/dist/cjs/messages/core.cjs.map +1 -1
- package/dist/cjs/messages/format.cjs +131 -42
- package/dist/cjs/messages/format.cjs.map +1 -1
- package/dist/cjs/messages/index.cjs +2 -0
- package/dist/cjs/messages/prune.cjs +12 -7
- package/dist/cjs/messages/prune.cjs.map +1 -1
- package/dist/cjs/messages/reasoningTypes.cjs +21 -0
- package/dist/cjs/messages/reasoningTypes.cjs.map +1 -0
- package/dist/cjs/messages/recency.cjs +15 -94
- package/dist/cjs/messages/recency.cjs.map +1 -1
- package/dist/cjs/messages/toolHistoryProjection.cjs +243 -0
- package/dist/cjs/messages/toolHistoryProjection.cjs.map +1 -0
- package/dist/cjs/messages/toolResultTypes.cjs +145 -4
- package/dist/cjs/messages/toolResultTypes.cjs.map +1 -1
- package/dist/cjs/run.cjs +5 -4
- package/dist/cjs/run.cjs.map +1 -1
- package/dist/cjs/session/AgentSession.cjs +6 -4
- package/dist/cjs/session/AgentSession.cjs.map +1 -1
- package/dist/cjs/session/JsonlSessionStore.cjs +3 -0
- package/dist/cjs/session/JsonlSessionStore.cjs.map +1 -1
- package/dist/cjs/session/index.cjs +1 -1
- package/dist/cjs/session/sessionProjection.cjs +75 -0
- package/dist/cjs/session/sessionProjection.cjs.map +1 -0
- package/dist/cjs/stream.cjs +18 -17
- package/dist/cjs/stream.cjs.map +1 -1
- package/dist/cjs/summarization/index.cjs.map +1 -1
- package/dist/cjs/summarization/node.cjs +18 -8
- package/dist/cjs/summarization/node.cjs.map +1 -1
- package/dist/cjs/summarization/shared.cjs +9 -0
- package/dist/cjs/summarization/shared.cjs.map +1 -1
- package/dist/cjs/tools/ArtifactDelivery.cjs +27 -0
- package/dist/cjs/tools/ArtifactDelivery.cjs.map +1 -0
- package/dist/cjs/tools/BashExecutor.cjs +6 -1
- package/dist/cjs/tools/BashExecutor.cjs.map +1 -1
- package/dist/cjs/tools/CodeExecutor.cjs +6 -1
- package/dist/cjs/tools/CodeExecutor.cjs.map +1 -1
- package/dist/cjs/tools/ProgrammaticToolCalling.cjs +5 -1
- package/dist/cjs/tools/ProgrammaticToolCalling.cjs.map +1 -1
- package/dist/cjs/tools/local/CompileCheckTool.cjs +1 -1
- package/dist/cjs/tools/local/LocalCodingTools.cjs +1 -1
- package/dist/cjs/utils/events.cjs +13 -0
- package/dist/cjs/utils/events.cjs.map +1 -1
- package/dist/cjs/utils/tokens.cjs +105 -0
- package/dist/cjs/utils/tokens.cjs.map +1 -1
- package/dist/esm/agents/AgentContext.mjs +13 -3
- package/dist/esm/agents/AgentContext.mjs.map +1 -1
- package/dist/esm/graphs/Graph.mjs +176 -55
- package/dist/esm/graphs/Graph.mjs.map +1 -1
- package/dist/esm/graphs/MultiAgentGraph.mjs +15 -5
- package/dist/esm/graphs/MultiAgentGraph.mjs.map +1 -1
- package/dist/esm/langfuse.mjs +49 -4
- package/dist/esm/langfuse.mjs.map +1 -1
- package/dist/esm/langfuseToolOutputTracing.mjs +41 -1
- package/dist/esm/langfuseToolOutputTracing.mjs.map +1 -1
- package/dist/esm/langfuseTraceShaping.mjs +7 -1
- package/dist/esm/langfuseTraceShaping.mjs.map +1 -1
- package/dist/esm/llm/anthropic/utils/message_inputs.mjs +5 -9
- package/dist/esm/llm/anthropic/utils/message_inputs.mjs.map +1 -1
- package/dist/esm/llm/bedrock/utils/message_inputs.mjs +2 -7
- package/dist/esm/llm/bedrock/utils/message_inputs.mjs.map +1 -1
- package/dist/esm/llm/contextPressureMeter.mjs +52 -11
- package/dist/esm/llm/contextPressureMeter.mjs.map +1 -1
- package/dist/esm/llm/init.mjs +1 -1
- package/dist/esm/llm/invoke.mjs +2 -2
- package/dist/esm/llm/openai/index.mjs +2 -1
- package/dist/esm/llm/openai/index.mjs.map +1 -1
- package/dist/esm/llm/openai/utils/index.mjs +5 -4
- package/dist/esm/llm/openai/utils/index.mjs.map +1 -1
- package/dist/esm/llm/preempt.mjs +2 -1
- package/dist/esm/llm/preempt.mjs.map +1 -1
- package/dist/esm/llm/prepareProviderRequest.mjs +9 -7
- package/dist/esm/llm/prepareProviderRequest.mjs.map +1 -1
- package/dist/esm/llm/providers.mjs +1 -1
- package/dist/esm/main.mjs +10 -7
- package/dist/esm/messages/alternation.mjs +2 -6
- package/dist/esm/messages/alternation.mjs.map +1 -1
- package/dist/esm/messages/budget.mjs +206 -8
- package/dist/esm/messages/budget.mjs.map +1 -1
- package/dist/esm/messages/cache.mjs +3 -9
- package/dist/esm/messages/cache.mjs.map +1 -1
- package/dist/esm/messages/core.mjs +23 -33
- package/dist/esm/messages/core.mjs.map +1 -1
- package/dist/esm/messages/format.mjs +132 -43
- package/dist/esm/messages/format.mjs.map +1 -1
- package/dist/esm/messages/index.mjs +2 -0
- package/dist/esm/messages/prune.mjs +12 -7
- package/dist/esm/messages/prune.mjs.map +1 -1
- package/dist/esm/messages/reasoningTypes.mjs +20 -0
- package/dist/esm/messages/reasoningTypes.mjs.map +1 -0
- package/dist/esm/messages/recency.mjs +16 -95
- package/dist/esm/messages/recency.mjs.map +1 -1
- package/dist/esm/messages/toolHistoryProjection.mjs +237 -0
- package/dist/esm/messages/toolHistoryProjection.mjs.map +1 -0
- package/dist/esm/messages/toolResultTypes.mjs +141 -4
- package/dist/esm/messages/toolResultTypes.mjs.map +1 -1
- package/dist/esm/run.mjs +5 -4
- package/dist/esm/run.mjs.map +1 -1
- package/dist/esm/session/AgentSession.mjs +6 -4
- package/dist/esm/session/AgentSession.mjs.map +1 -1
- package/dist/esm/session/JsonlSessionStore.mjs +3 -0
- package/dist/esm/session/JsonlSessionStore.mjs.map +1 -1
- package/dist/esm/session/index.mjs +1 -1
- package/dist/esm/session/sessionProjection.mjs +72 -0
- package/dist/esm/session/sessionProjection.mjs.map +1 -0
- package/dist/esm/stream.mjs +15 -14
- package/dist/esm/stream.mjs.map +1 -1
- package/dist/esm/summarization/index.mjs.map +1 -1
- package/dist/esm/summarization/node.mjs +19 -9
- package/dist/esm/summarization/node.mjs.map +1 -1
- package/dist/esm/summarization/shared.mjs +9 -1
- package/dist/esm/summarization/shared.mjs.map +1 -1
- package/dist/esm/tools/ArtifactDelivery.mjs +26 -0
- package/dist/esm/tools/ArtifactDelivery.mjs.map +1 -0
- package/dist/esm/tools/BashExecutor.mjs +6 -1
- package/dist/esm/tools/BashExecutor.mjs.map +1 -1
- package/dist/esm/tools/CodeExecutor.mjs +6 -1
- package/dist/esm/tools/CodeExecutor.mjs.map +1 -1
- package/dist/esm/tools/ProgrammaticToolCalling.mjs +5 -1
- package/dist/esm/tools/ProgrammaticToolCalling.mjs.map +1 -1
- package/dist/esm/tools/local/CompileCheckTool.mjs +1 -1
- package/dist/esm/tools/local/LocalCodingTools.mjs +1 -1
- package/dist/esm/utils/events.mjs +13 -0
- package/dist/esm/utils/events.mjs.map +1 -1
- package/dist/esm/utils/tokens.mjs +105 -1
- package/dist/esm/utils/tokens.mjs.map +1 -1
- package/dist/types/agents/AgentContext.d.ts +13 -1
- package/dist/types/graphs/Graph.d.ts +27 -0
- package/dist/types/hooks/types.d.ts +4 -2
- package/dist/types/index.d.ts +1 -0
- package/dist/types/langfuse.d.ts +10 -0
- package/dist/types/langfuseToolOutputTracing.d.ts +2 -0
- package/dist/types/llm/contextPressureMeter.d.ts +2 -1
- package/dist/types/llm/prepareProviderRequest.d.ts +7 -1
- package/dist/types/messages/budget.d.ts +15 -10
- package/dist/types/messages/core.d.ts +8 -17
- package/dist/types/messages/format.d.ts +3 -2
- package/dist/types/messages/index.d.ts +1 -1
- package/dist/types/messages/prune.d.ts +1 -1
- package/dist/types/messages/reasoningTypes.d.ts +7 -0
- package/dist/types/messages/recency.d.ts +3 -0
- package/dist/types/messages/toolHistoryProjection.d.ts +65 -0
- package/dist/types/messages/toolResultTypes.d.ts +31 -1
- package/dist/types/session/sessionProjection.d.ts +10 -0
- package/dist/types/summarization/index.d.ts +2 -1
- package/dist/types/summarization/node.d.ts +1 -0
- package/dist/types/summarization/shared.d.ts +12 -0
- package/dist/types/tools/ArtifactDelivery.d.ts +4 -0
- package/dist/types/types/graph.d.ts +28 -0
- package/dist/types/types/run.d.ts +4 -0
- package/dist/types/types/summarize.d.ts +4 -1
- package/dist/types/types/tools.d.ts +11 -0
- package/dist/types/utils/tokens.d.ts +2 -1
- package/package.json +1 -1
- package/src/agents/AgentContext.ts +34 -3
- package/src/graphs/Graph.ts +465 -147
- package/src/graphs/MultiAgentGraph.ts +28 -6
- package/src/hooks/types.ts +4 -1
- package/src/index.ts +1 -0
- package/src/langfuse.ts +84 -11
- package/src/langfuseToolOutputTracing.ts +91 -0
- package/src/langfuseTraceShaping.ts +17 -4
- package/src/llm/anthropic/utils/message_inputs.ts +5 -10
- package/src/llm/bedrock/utils/message_inputs.ts +2 -8
- package/src/llm/contextPressureMeter.ts +80 -12
- package/src/llm/openai/utils/index.ts +5 -4
- package/src/llm/prepareProviderRequest.ts +21 -16
- package/src/messages/alternation.ts +2 -15
- package/src/messages/budget.ts +439 -23
- package/src/messages/cache.ts +8 -9
- package/src/messages/core.ts +65 -95
- package/src/messages/format.ts +262 -78
- package/src/messages/index.ts +1 -1
- package/src/messages/prune.ts +31 -12
- package/src/messages/reasoningTypes.ts +23 -0
- package/src/messages/recency.ts +35 -179
- package/src/messages/toolHistoryProjection.ts +460 -0
- package/src/messages/toolResultTypes.ts +331 -100
- package/src/run.ts +10 -2
- package/src/session/AgentSession.ts +33 -16
- package/src/session/JsonlSessionStore.ts +6 -0
- package/src/session/sessionProjection.ts +126 -0
- package/src/stream.ts +14 -19
- package/src/summarization/index.ts +2 -0
- package/src/summarization/node.ts +62 -13
- package/src/summarization/shared.ts +23 -0
- package/src/tools/ArtifactDelivery.ts +50 -0
- package/src/tools/BashExecutor.ts +18 -1
- package/src/tools/CodeExecutor.ts +18 -1
- package/src/tools/ProgrammaticToolCalling.ts +15 -1
- package/src/types/graph.ts +28 -0
- package/src/types/run.ts +4 -0
- package/src/types/summarize.ts +4 -1
- package/src/types/tools.ts +12 -0
- package/src/utils/events.ts +19 -0
- package/src/utils/tokens.ts +183 -0
package/src/messages/cache.ts
CHANGED
|
@@ -4,6 +4,7 @@ import type Anthropic from '@anthropic-ai/sdk';
|
|
|
4
4
|
import type { AnthropicMessage } from '@/types/messages';
|
|
5
5
|
import { hasComputerCallOutputMarker } from '@/utils/toolContent';
|
|
6
6
|
import { toLangChainContent } from './langchain';
|
|
7
|
+
import { isReasoningContentBlock } from './reasoningTypes';
|
|
7
8
|
import { ContentTypes } from '@/common/enum';
|
|
8
9
|
|
|
9
10
|
type MessageWithContent = {
|
|
@@ -412,27 +413,25 @@ function isCachePoint(block: unknown): boolean {
|
|
|
412
413
|
* loses tail caching, so all of these are excluded.
|
|
413
414
|
*/
|
|
414
415
|
const NON_ANCHORABLE_BLOCK_TYPES = new Set([
|
|
415
|
-
'thinking',
|
|
416
|
-
'redacted_thinking',
|
|
417
|
-
'reasoning_content',
|
|
418
|
-
'reasoning',
|
|
419
|
-
'think',
|
|
420
416
|
'input_json_delta',
|
|
421
417
|
]);
|
|
422
418
|
|
|
423
419
|
/**
|
|
424
420
|
* A block can anchor the tail cache breakpoint when it is a real content block
|
|
425
421
|
* that the Anthropic API accepts `cache_control` on and that survives provider
|
|
426
|
-
* conversion. Reasoning
|
|
427
|
-
*
|
|
428
|
-
* so both are skipped.
|
|
422
|
+
* conversion. Reasoning and dropped-delta blocks are excluded, and empty text
|
|
423
|
+
* blocks are not cacheable, so all are skipped.
|
|
429
424
|
*/
|
|
430
425
|
function isTailCacheableBlock(block: MessageContentComplex): boolean {
|
|
431
426
|
if (isCachePoint(block)) {
|
|
432
427
|
return false;
|
|
433
428
|
}
|
|
434
429
|
const type = (block as { type?: string }).type;
|
|
435
|
-
if (
|
|
430
|
+
if (
|
|
431
|
+
type == null ||
|
|
432
|
+
isReasoningContentBlock(block) ||
|
|
433
|
+
NON_ANCHORABLE_BLOCK_TYPES.has(type)
|
|
434
|
+
) {
|
|
436
435
|
return false;
|
|
437
436
|
}
|
|
438
437
|
if (type === 'text') {
|
package/src/messages/core.ts
CHANGED
|
@@ -11,6 +11,11 @@ import type { ContentBlock as LangChainContentBlock } from '@langchain/core/mess
|
|
|
11
11
|
import type { ToolCall, ToolCallChunk } from '@langchain/core/messages/tool';
|
|
12
12
|
import type { ProviderMessageProvenancePart } from './provenance';
|
|
13
13
|
import type * as t from '@/types';
|
|
14
|
+
import type {
|
|
15
|
+
ResponsesReplayPosition,
|
|
16
|
+
ToolHistoryPreparation,
|
|
17
|
+
OrderedToolHistoryProjection,
|
|
18
|
+
} from './toolHistoryProjection';
|
|
14
19
|
import {
|
|
15
20
|
cloneToolMessageWithContent,
|
|
16
21
|
compactToolContent,
|
|
@@ -31,8 +36,16 @@ import {
|
|
|
31
36
|
} from './provenance';
|
|
32
37
|
import { HARD_MAX_TOOL_RESULT_CHARS } from '@/utils/truncation';
|
|
33
38
|
import { stripAnthropicCacheControl } from './cache';
|
|
39
|
+
import { isReasoningContentBlock } from './reasoningTypes';
|
|
34
40
|
import { ContentTypes, Providers } from '@/common';
|
|
35
41
|
import { toLangChainContent } from './langchain';
|
|
42
|
+
import {
|
|
43
|
+
OPENAI_RESPONSES_REPLAY_POSITIONS_KEY,
|
|
44
|
+
createToolHistoryPreparation,
|
|
45
|
+
getGeneratedImageMimeType,
|
|
46
|
+
getResponsesHistorySource,
|
|
47
|
+
isResponsesReplayPosition,
|
|
48
|
+
} from './toolHistoryProjection';
|
|
36
49
|
|
|
37
50
|
type ReasoningSummary = { summary?: Array<{ text?: string }> };
|
|
38
51
|
type ReasoningDetail = { type?: string; text?: string };
|
|
@@ -227,8 +240,7 @@ function getAdditionalReasoningContent(
|
|
|
227
240
|
/**
|
|
228
241
|
* True when a content block is a provider reasoning block: Anthropic
|
|
229
242
|
* `thinking` / `redacted_thinking`, Google `reasoning`, Bedrock
|
|
230
|
-
* `reasoning_content`, and
|
|
231
|
-
* those names.
|
|
243
|
+
* `reasoning_content`, LibreChat `think`, and their known streamed variants.
|
|
232
244
|
*
|
|
233
245
|
* Shared rather than re-derived because two very different readers must agree
|
|
234
246
|
* on the same answer: the stream classifier, which decides what the host has
|
|
@@ -236,38 +248,18 @@ function getAdditionalReasoningContent(
|
|
|
236
248
|
* holds anything worth keeping. A turn the host renders as thinking-only must
|
|
237
249
|
* never look like a visible answer to the gate.
|
|
238
250
|
*
|
|
239
|
-
*
|
|
240
|
-
*
|
|
241
|
-
* carries the `reasoning` prefix.
|
|
251
|
+
* Exact matching prevents unrelated custom block types that happen to share a
|
|
252
|
+
* prefix from being silently classified as hidden reasoning.
|
|
242
253
|
*/
|
|
243
|
-
export
|
|
244
|
-
const type = block.type;
|
|
245
|
-
if (type == null) {
|
|
246
|
-
return false;
|
|
247
|
-
}
|
|
248
|
-
return (
|
|
249
|
-
type.startsWith(ContentTypes.THINKING) ||
|
|
250
|
-
type.startsWith(ContentTypes.REASONING) ||
|
|
251
|
-
type === 'redacted_thinking'
|
|
252
|
-
);
|
|
253
|
-
}
|
|
254
|
+
export { isReasoningContentBlock } from './reasoningTypes';
|
|
254
255
|
|
|
255
256
|
function hasReasoningContent(content: BaseMessage['content']): boolean {
|
|
256
257
|
if (!Array.isArray(content)) {
|
|
257
258
|
return false;
|
|
258
259
|
}
|
|
259
|
-
return content.some(
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
}
|
|
263
|
-
return (
|
|
264
|
-
item.type === ContentTypes.THINK ||
|
|
265
|
-
item.type === ContentTypes.THINKING ||
|
|
266
|
-
item.type === ContentTypes.REASONING ||
|
|
267
|
-
item.type === ContentTypes.REASONING_CONTENT ||
|
|
268
|
-
item.type === 'redacted_thinking'
|
|
269
|
-
);
|
|
270
|
-
});
|
|
260
|
+
return content.some(
|
|
261
|
+
(item) => typeof item === 'object' && isReasoningContentBlock(item)
|
|
262
|
+
);
|
|
271
263
|
}
|
|
272
264
|
|
|
273
265
|
export function modifyDeltaProperties(
|
|
@@ -856,19 +848,13 @@ function hasReplayableEncryptedReasoning(reasoning: unknown): boolean {
|
|
|
856
848
|
|
|
857
849
|
type ResponsesReplayProjection = 'fallback' | 'native';
|
|
858
850
|
|
|
859
|
-
export
|
|
860
|
-
'__openai_responses_replay_positions__';
|
|
851
|
+
export { OPENAI_RESPONSES_REPLAY_POSITIONS_KEY } from './toolHistoryProjection';
|
|
861
852
|
|
|
862
853
|
/** Reasoning item currently streaming, so a terminal ciphertext seals against its own id. */
|
|
863
854
|
export const OPENAI_RESPONSES_ACTIVE_REASONING_ID_KEY =
|
|
864
855
|
'__openai_responses_active_reasoning_id__';
|
|
865
856
|
|
|
866
|
-
export type ResponsesReplayPosition
|
|
867
|
-
contentIndex?: number;
|
|
868
|
-
itemId: string;
|
|
869
|
-
kind: 'message' | 'output' | 'reasoning' | 'text';
|
|
870
|
-
outputIndex: number;
|
|
871
|
-
};
|
|
857
|
+
export type { ResponsesReplayPosition } from './toolHistoryProjection';
|
|
872
858
|
|
|
873
859
|
type CompletedGeneratedImages = {
|
|
874
860
|
blocks: PositionedResponsesReplayBlock[];
|
|
@@ -1297,56 +1283,7 @@ function projectPreemptedResponsesV1Content(
|
|
|
1297
1283
|
}
|
|
1298
1284
|
|
|
1299
1285
|
function getAuthoritativeResponsesOutput(message: AIMessage): unknown[] {
|
|
1300
|
-
|
|
1301
|
-
const toolOutputs = message.additional_kwargs.tool_outputs;
|
|
1302
|
-
if (Array.isArray(responseOutput) && responseOutput.length > 0) {
|
|
1303
|
-
return responseOutput;
|
|
1304
|
-
}
|
|
1305
|
-
return Array.isArray(toolOutputs) ? toolOutputs : [];
|
|
1306
|
-
}
|
|
1307
|
-
|
|
1308
|
-
function isResponsesReplayPosition(
|
|
1309
|
-
value: unknown
|
|
1310
|
-
): value is ResponsesReplayPosition {
|
|
1311
|
-
if (value == null || typeof value !== 'object') {
|
|
1312
|
-
return false;
|
|
1313
|
-
}
|
|
1314
|
-
const position = value as Partial<ResponsesReplayPosition>;
|
|
1315
|
-
return (
|
|
1316
|
-
(position.kind === 'message' ||
|
|
1317
|
-
position.kind === 'output' ||
|
|
1318
|
-
position.kind === 'reasoning' ||
|
|
1319
|
-
position.kind === 'text') &&
|
|
1320
|
-
typeof position.itemId === 'string' &&
|
|
1321
|
-
position.itemId.length > 0 &&
|
|
1322
|
-
typeof position.outputIndex === 'number' &&
|
|
1323
|
-
Number.isSafeInteger(position.outputIndex) &&
|
|
1324
|
-
position.outputIndex >= 0 &&
|
|
1325
|
-
(position.contentIndex == null ||
|
|
1326
|
-
(typeof position.contentIndex === 'number' &&
|
|
1327
|
-
Number.isSafeInteger(position.contentIndex) &&
|
|
1328
|
-
position.contentIndex >= 0))
|
|
1329
|
-
);
|
|
1330
|
-
}
|
|
1331
|
-
|
|
1332
|
-
function getGeneratedImageMimeType(data: string): string {
|
|
1333
|
-
const bytes = Buffer.from(data.slice(0, 16), 'base64');
|
|
1334
|
-
if (bytes[0] === 0xff && bytes[1] === 0xd8 && bytes[2] === 0xff) {
|
|
1335
|
-
return 'image/jpeg';
|
|
1336
|
-
}
|
|
1337
|
-
if (
|
|
1338
|
-
bytes[0] === 0x52 &&
|
|
1339
|
-
bytes[1] === 0x49 &&
|
|
1340
|
-
bytes[2] === 0x46 &&
|
|
1341
|
-
bytes[3] === 0x46 &&
|
|
1342
|
-
bytes[8] === 0x57 &&
|
|
1343
|
-
bytes[9] === 0x45 &&
|
|
1344
|
-
bytes[10] === 0x42 &&
|
|
1345
|
-
bytes[11] === 0x50
|
|
1346
|
-
) {
|
|
1347
|
-
return 'image/webp';
|
|
1348
|
-
}
|
|
1349
|
-
return 'image/png';
|
|
1286
|
+
return getResponsesHistorySource(message)?.items ?? [];
|
|
1350
1287
|
}
|
|
1351
1288
|
|
|
1352
1289
|
function getResponsesReplayItemKey(
|
|
@@ -1382,7 +1319,8 @@ function getResponsesReplayArtifacts(
|
|
|
1382
1319
|
output: readonly unknown[],
|
|
1383
1320
|
maxChars: number,
|
|
1384
1321
|
replayProjection: ResponsesReplayProjection,
|
|
1385
|
-
replayPositionValue?: unknown
|
|
1322
|
+
replayPositionValue?: unknown,
|
|
1323
|
+
history?: OrderedToolHistoryProjection
|
|
1386
1324
|
): ResponsesReplayArtifacts {
|
|
1387
1325
|
const blocks: PositionedResponsesReplayBlock[] = [];
|
|
1388
1326
|
const data = new Set<string>();
|
|
@@ -1441,7 +1379,11 @@ function getResponsesReplayArtifacts(
|
|
|
1441
1379
|
kind: 'message',
|
|
1442
1380
|
outputIndex,
|
|
1443
1381
|
});
|
|
1444
|
-
if (
|
|
1382
|
+
if (
|
|
1383
|
+
history != null ||
|
|
1384
|
+
!('content' in item) ||
|
|
1385
|
+
!Array.isArray(item.content)
|
|
1386
|
+
) {
|
|
1445
1387
|
continue;
|
|
1446
1388
|
}
|
|
1447
1389
|
for (
|
|
@@ -1473,6 +1415,24 @@ function getResponsesReplayArtifacts(
|
|
|
1473
1415
|
});
|
|
1474
1416
|
}
|
|
1475
1417
|
}
|
|
1418
|
+
if (history?.source.coverage === 'complete-output') {
|
|
1419
|
+
for (const contribution of history.contributions) {
|
|
1420
|
+
if (contribution.kind !== 'text') {
|
|
1421
|
+
continue;
|
|
1422
|
+
}
|
|
1423
|
+
const itemId =
|
|
1424
|
+
contribution.itemId ?? `message-${contribution.outputIndex}`;
|
|
1425
|
+
textPositionsByKey.set(
|
|
1426
|
+
`${itemId}:${contribution.outputIndex}:${contribution.contentIndex ?? 0}`,
|
|
1427
|
+
{
|
|
1428
|
+
itemId,
|
|
1429
|
+
kind: 'text',
|
|
1430
|
+
outputIndex: contribution.outputIndex,
|
|
1431
|
+
contentIndex: contribution.contentIndex,
|
|
1432
|
+
}
|
|
1433
|
+
);
|
|
1434
|
+
}
|
|
1435
|
+
}
|
|
1476
1436
|
if (hasAuthoritativeMessage) {
|
|
1477
1437
|
for (const [itemId, outputIndex] of authoritativeOutputIndicesByItemId) {
|
|
1478
1438
|
outputPositionsByItemId.set(itemId, {
|
|
@@ -1918,7 +1878,8 @@ function isPreemptedOpenAIResponsesMessage(message: AIMessage): boolean {
|
|
|
1918
1878
|
function projectPreemptedOpenAIResponsesMessage(
|
|
1919
1879
|
message: AIMessage,
|
|
1920
1880
|
maxChars: number,
|
|
1921
|
-
replayProjection: ResponsesReplayProjection
|
|
1881
|
+
replayProjection: ResponsesReplayProjection,
|
|
1882
|
+
preparation: ToolHistoryPreparation = createToolHistoryPreparation()
|
|
1922
1883
|
): AIMessage {
|
|
1923
1884
|
if (!isPreemptedOpenAIResponsesMessage(message)) {
|
|
1924
1885
|
return message;
|
|
@@ -1929,7 +1890,9 @@ function projectPreemptedOpenAIResponsesMessage(
|
|
|
1929
1890
|
const retainsEncryptedReasoning =
|
|
1930
1891
|
replayProjection === 'native' &&
|
|
1931
1892
|
hasReplayableEncryptedReasoning(additionalKwargs.reasoning);
|
|
1932
|
-
const
|
|
1893
|
+
const history = preparation.get(message);
|
|
1894
|
+
const authoritativeOutput =
|
|
1895
|
+
history?.source.items ?? getAuthoritativeResponsesOutput(message);
|
|
1933
1896
|
const {
|
|
1934
1897
|
generatedImages,
|
|
1935
1898
|
messagePositions,
|
|
@@ -1941,7 +1904,8 @@ function projectPreemptedOpenAIResponsesMessage(
|
|
|
1941
1904
|
authoritativeOutput,
|
|
1942
1905
|
maxChars,
|
|
1943
1906
|
replayProjection,
|
|
1944
|
-
additionalKwargs[OPENAI_RESPONSES_REPLAY_POSITIONS_KEY]
|
|
1907
|
+
additionalKwargs[OPENAI_RESPONSES_REPLAY_POSITIONS_KEY],
|
|
1908
|
+
history
|
|
1945
1909
|
);
|
|
1946
1910
|
const reasoningItemId =
|
|
1947
1911
|
retainsEncryptedReasoning &&
|
|
@@ -2043,7 +2007,8 @@ function projectPreemptedOpenAIResponsesMessage(
|
|
|
2043
2007
|
export function projectToolStreamContentForProvider(
|
|
2044
2008
|
messages: BaseMessage[],
|
|
2045
2009
|
responsesReplayProjection?: ResponsesReplayProjection,
|
|
2046
|
-
maxChars = HARD_MAX_TOOL_RESULT_CHARS
|
|
2010
|
+
maxChars = HARD_MAX_TOOL_RESULT_CHARS,
|
|
2011
|
+
preparation: ToolHistoryPreparation = createToolHistoryPreparation()
|
|
2047
2012
|
): BaseMessage[] {
|
|
2048
2013
|
let projected: BaseMessage[] | undefined;
|
|
2049
2014
|
for (let i = 0; i < messages.length; i++) {
|
|
@@ -2059,7 +2024,8 @@ export function projectToolStreamContentForProvider(
|
|
|
2059
2024
|
const replaySafeMessage = projectPreemptedOpenAIResponsesMessage(
|
|
2060
2025
|
assistantMessage,
|
|
2061
2026
|
maxChars,
|
|
2062
|
-
responsesReplayProjection
|
|
2027
|
+
responsesReplayProjection,
|
|
2028
|
+
preparation
|
|
2063
2029
|
);
|
|
2064
2030
|
if (replaySafeMessage !== assistantMessage) {
|
|
2065
2031
|
projected ??= [...messages];
|
|
@@ -2798,14 +2764,18 @@ export function findLastIndex<T>(
|
|
|
2798
2764
|
function readOwnDataProperty(target: object, key: PropertyKey): unknown {
|
|
2799
2765
|
try {
|
|
2800
2766
|
const descriptor = Object.getOwnPropertyDescriptor(target, key);
|
|
2801
|
-
return descriptor != null && 'value' in descriptor
|
|
2767
|
+
return descriptor != null && 'value' in descriptor
|
|
2768
|
+
? descriptor.value
|
|
2769
|
+
: undefined;
|
|
2802
2770
|
} catch {
|
|
2803
2771
|
return undefined;
|
|
2804
2772
|
}
|
|
2805
2773
|
}
|
|
2806
2774
|
|
|
2807
2775
|
/** Whether message content carries non-whitespace text in any text block. */
|
|
2808
|
-
export function hasNonEmptyTextContent(
|
|
2776
|
+
export function hasNonEmptyTextContent(
|
|
2777
|
+
content: BaseMessage['content']
|
|
2778
|
+
): boolean {
|
|
2809
2779
|
if (typeof content === 'string') {
|
|
2810
2780
|
return content.trim() !== '';
|
|
2811
2781
|
}
|