@librechat/agents 3.7.15 → 3.7.17
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 +91 -0
- package/dist/cjs/agents/AgentContext.cjs.map +1 -1
- package/dist/cjs/agents/projection.cjs +2 -1
- package/dist/cjs/agents/projection.cjs.map +1 -1
- package/dist/cjs/graphs/Graph.cjs +47 -6
- package/dist/cjs/graphs/Graph.cjs.map +1 -1
- package/dist/cjs/graphs/MultiAgentGraph.cjs +20 -7
- package/dist/cjs/graphs/MultiAgentGraph.cjs.map +1 -1
- package/dist/cjs/llm/anthropic/utils/message_inputs.cjs +1 -1
- package/dist/cjs/llm/openai/utils/index.cjs +1 -1
- package/dist/cjs/llm/openai/utils/index.cjs.map +1 -1
- package/dist/cjs/llm/preempt.cjs +1 -10
- package/dist/cjs/llm/preempt.cjs.map +1 -1
- package/dist/cjs/main.cjs +23 -3
- package/dist/cjs/messages/contextPruning.cjs +1 -1
- package/dist/cjs/messages/contextPruning.cjs.map +1 -1
- package/dist/cjs/messages/core.cjs +29 -1
- package/dist/cjs/messages/core.cjs.map +1 -1
- package/dist/cjs/messages/fading.cjs +122 -0
- package/dist/cjs/messages/fading.cjs.map +1 -0
- package/dist/cjs/messages/format.cjs +1 -1
- package/dist/cjs/messages/index.cjs +1 -0
- package/dist/cjs/messages/prune.cjs +364 -236
- package/dist/cjs/messages/prune.cjs.map +1 -1
- package/dist/cjs/run.cjs +27 -0
- package/dist/cjs/run.cjs.map +1 -1
- package/dist/cjs/session/AgentSession.cjs +213 -8
- package/dist/cjs/session/AgentSession.cjs.map +1 -1
- package/dist/cjs/session/JsonlSessionStore.cjs +41 -0
- package/dist/cjs/session/JsonlSessionStore.cjs.map +1 -1
- package/dist/cjs/session/index.cjs +1 -1
- package/dist/cjs/stream.cjs +1 -1
- package/dist/cjs/summarization/node.cjs +1 -1
- package/dist/cjs/tools/ToolNode.cjs +1 -1
- package/dist/cjs/tools/subagent/SubagentExecutor.cjs +2 -0
- package/dist/cjs/tools/subagent/SubagentExecutor.cjs.map +1 -1
- package/dist/cjs/tools/subagent/SubagentReplay.cjs +2 -1
- package/dist/cjs/tools/subagent/SubagentReplay.cjs.map +1 -1
- package/dist/cjs/utils/errors.cjs +3 -1
- package/dist/cjs/utils/errors.cjs.map +1 -1
- package/dist/cjs/utils/index.cjs +1 -1
- package/dist/cjs/utils/truncation.cjs +9 -0
- package/dist/cjs/utils/truncation.cjs.map +1 -1
- package/dist/esm/agents/AgentContext.mjs +92 -1
- package/dist/esm/agents/AgentContext.mjs.map +1 -1
- package/dist/esm/agents/projection.mjs +2 -1
- package/dist/esm/agents/projection.mjs.map +1 -1
- package/dist/esm/graphs/Graph.mjs +47 -6
- package/dist/esm/graphs/Graph.mjs.map +1 -1
- package/dist/esm/graphs/MultiAgentGraph.mjs +20 -7
- package/dist/esm/graphs/MultiAgentGraph.mjs.map +1 -1
- package/dist/esm/llm/anthropic/utils/message_inputs.mjs +1 -1
- package/dist/esm/llm/openai/utils/index.mjs +2 -2
- package/dist/esm/llm/openai/utils/index.mjs.map +1 -1
- package/dist/esm/llm/preempt.mjs +1 -10
- package/dist/esm/llm/preempt.mjs.map +1 -1
- package/dist/esm/main.mjs +6 -5
- package/dist/esm/messages/contextPruning.mjs +1 -1
- package/dist/esm/messages/contextPruning.mjs.map +1 -1
- package/dist/esm/messages/core.mjs +29 -2
- package/dist/esm/messages/core.mjs.map +1 -1
- package/dist/esm/messages/fading.mjs +108 -0
- package/dist/esm/messages/fading.mjs.map +1 -0
- package/dist/esm/messages/format.mjs +1 -1
- package/dist/esm/messages/index.mjs +1 -0
- package/dist/esm/messages/prune.mjs +363 -235
- package/dist/esm/messages/prune.mjs.map +1 -1
- package/dist/esm/run.mjs +27 -0
- package/dist/esm/run.mjs.map +1 -1
- package/dist/esm/session/AgentSession.mjs +213 -8
- package/dist/esm/session/AgentSession.mjs.map +1 -1
- package/dist/esm/session/JsonlSessionStore.mjs +41 -0
- package/dist/esm/session/JsonlSessionStore.mjs.map +1 -1
- package/dist/esm/session/index.mjs +1 -1
- package/dist/esm/stream.mjs +1 -1
- package/dist/esm/summarization/node.mjs +1 -1
- package/dist/esm/tools/ToolNode.mjs +1 -1
- package/dist/esm/tools/subagent/SubagentExecutor.mjs +2 -0
- package/dist/esm/tools/subagent/SubagentExecutor.mjs.map +1 -1
- package/dist/esm/tools/subagent/SubagentReplay.mjs +2 -1
- package/dist/esm/tools/subagent/SubagentReplay.mjs.map +1 -1
- package/dist/esm/utils/errors.mjs +3 -1
- package/dist/esm/utils/errors.mjs.map +1 -1
- package/dist/esm/utils/index.mjs +1 -1
- package/dist/esm/utils/truncation.mjs +7 -1
- package/dist/esm/utils/truncation.mjs.map +1 -1
- package/dist/types/agents/AgentContext.d.ts +32 -1
- package/dist/types/agents/projection.d.ts +3 -1
- package/dist/types/graphs/Graph.d.ts +14 -1
- package/dist/types/graphs/MultiAgentGraph.d.ts +7 -0
- package/dist/types/messages/contextPruning.d.ts +2 -0
- package/dist/types/messages/core.d.ts +2 -0
- package/dist/types/messages/fading.d.ts +81 -0
- package/dist/types/messages/index.d.ts +1 -0
- package/dist/types/messages/prune.d.ts +71 -24
- package/dist/types/run.d.ts +16 -0
- package/dist/types/session/AgentSession.d.ts +15 -0
- package/dist/types/session/JsonlSessionStore.d.ts +4 -1
- package/dist/types/session/types.d.ts +9 -0
- package/dist/types/tools/subagent/SubagentReplay.d.ts +3 -1
- package/dist/types/types/graph.d.ts +23 -0
- package/dist/types/types/run.d.ts +10 -0
- package/dist/types/utils/truncation.d.ts +9 -0
- package/package.json +1 -1
- package/src/agents/AgentContext.ts +175 -1
- package/src/agents/projection.ts +4 -0
- package/src/graphs/Graph.ts +97 -11
- package/src/graphs/MultiAgentGraph.ts +54 -6
- package/src/llm/openai/utils/index.ts +3 -1
- package/src/llm/preempt.ts +4 -17
- package/src/messages/contextPruning.ts +7 -1
- package/src/messages/core.ts +52 -0
- package/src/messages/fading.ts +301 -0
- package/src/messages/index.ts +1 -0
- package/src/messages/prune.ts +719 -507
- package/src/run.ts +52 -0
- package/src/session/AgentSession.ts +397 -8
- package/src/session/JsonlSessionStore.ts +71 -0
- package/src/session/types.ts +10 -0
- package/src/tools/subagent/SubagentExecutor.ts +6 -0
- package/src/tools/subagent/SubagentReplay.ts +15 -2
- package/src/types/graph.ts +25 -0
- package/src/types/run.ts +10 -0
- package/src/utils/errors.ts +17 -1
- package/src/utils/truncation.ts +25 -0
|
@@ -26,6 +26,7 @@ import type {
|
|
|
26
26
|
SessionRunEventEntry,
|
|
27
27
|
SessionSummaryEntry,
|
|
28
28
|
SessionStateEntry,
|
|
29
|
+
SessionFadingState,
|
|
29
30
|
SessionTreeNode,
|
|
30
31
|
} from './types';
|
|
31
32
|
import {
|
|
@@ -82,6 +83,16 @@ function parseLine(line: string): SessionHeader | SessionEntry | undefined {
|
|
|
82
83
|
}
|
|
83
84
|
}
|
|
84
85
|
|
|
86
|
+
/** A `session_state` line may carry `data: null`; only an object can hold fading state. */
|
|
87
|
+
function hasFadingStateField(entry: SessionStateEntry): boolean {
|
|
88
|
+
const data: unknown = entry.data;
|
|
89
|
+
return (
|
|
90
|
+
data != null &&
|
|
91
|
+
typeof data === 'object' &&
|
|
92
|
+
Object.prototype.hasOwnProperty.call(data, 'fadingState')
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
|
|
85
96
|
function createHeader(options: CreateSessionFileOptions): SessionHeader {
|
|
86
97
|
return {
|
|
87
98
|
type: 'session',
|
|
@@ -374,6 +385,66 @@ export class JsonlSessionStore {
|
|
|
374
385
|
});
|
|
375
386
|
}
|
|
376
387
|
|
|
388
|
+
getFadingStates(
|
|
389
|
+
mainThreadId?: string,
|
|
390
|
+
maxAlternateStates = Number.POSITIVE_INFINITY
|
|
391
|
+
): SessionFadingState[] {
|
|
392
|
+
const states = new Map<string, SessionFadingState>();
|
|
393
|
+
const alternateLimit = Number.isFinite(maxAlternateStates)
|
|
394
|
+
? Math.max(0, Math.floor(maxAlternateStates))
|
|
395
|
+
: Number.POSITIVE_INFINITY;
|
|
396
|
+
let alternateCount = 0;
|
|
397
|
+
let mainFound = mainThreadId == null;
|
|
398
|
+
for (let i = this.entries.length - 1; i >= 0; i--) {
|
|
399
|
+
const entry = this.entries[i];
|
|
400
|
+
if (entry.type !== 'session_state' || !hasFadingStateField(entry)) {
|
|
401
|
+
continue;
|
|
402
|
+
}
|
|
403
|
+
if (entry.data.fadingState == null) {
|
|
404
|
+
break;
|
|
405
|
+
}
|
|
406
|
+
const state = entry.data.fadingState;
|
|
407
|
+
const scopeKey = JSON.stringify([
|
|
408
|
+
state.threadId,
|
|
409
|
+
state.checkpointNs ?? '',
|
|
410
|
+
]);
|
|
411
|
+
if (states.has(scopeKey)) {
|
|
412
|
+
continue;
|
|
413
|
+
}
|
|
414
|
+
if (
|
|
415
|
+
state.threadId === mainThreadId &&
|
|
416
|
+
(state.checkpointNs ?? '') === ''
|
|
417
|
+
) {
|
|
418
|
+
states.set(scopeKey, state);
|
|
419
|
+
mainFound = true;
|
|
420
|
+
} else if (alternateCount < alternateLimit) {
|
|
421
|
+
states.set(scopeKey, state);
|
|
422
|
+
alternateCount += 1;
|
|
423
|
+
}
|
|
424
|
+
if (mainFound && alternateCount >= alternateLimit) {
|
|
425
|
+
break;
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
return [...states.values()];
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
hasFadingState(): boolean {
|
|
432
|
+
return this.entries.some(
|
|
433
|
+
(entry) => entry.type === 'session_state' && hasFadingStateField(entry)
|
|
434
|
+
);
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
async appendFadingState(
|
|
438
|
+
fadingState: SessionStateEntry['data']['fadingState']
|
|
439
|
+
): Promise<SessionStateEntry> {
|
|
440
|
+
const leafId = this.getLeafEntry()?.id ?? null;
|
|
441
|
+
return this.appendEntry<SessionStateEntry>({
|
|
442
|
+
type: 'session_state',
|
|
443
|
+
parentId: leafId,
|
|
444
|
+
data: { leafId, fadingState },
|
|
445
|
+
});
|
|
446
|
+
}
|
|
447
|
+
|
|
377
448
|
async appendEntryForCompaction(params: {
|
|
378
449
|
text: string;
|
|
379
450
|
tokenCount?: number;
|
package/src/session/types.ts
CHANGED
|
@@ -116,10 +116,20 @@ export type SessionRunEventEntry = SessionEntryBase<
|
|
|
116
116
|
}
|
|
117
117
|
>;
|
|
118
118
|
|
|
119
|
+
export interface SessionFadingState {
|
|
120
|
+
threadId: string;
|
|
121
|
+
/** LangGraph checkpoint namespace within `threadId`; empty when omitted. */
|
|
122
|
+
checkpointNs?: string;
|
|
123
|
+
fadingTier?: t.FadingTier;
|
|
124
|
+
fadingTiers?: t.FadingTiers;
|
|
125
|
+
}
|
|
126
|
+
|
|
119
127
|
export type SessionStateEntry = SessionEntryBase<
|
|
120
128
|
'session_state',
|
|
121
129
|
{
|
|
122
130
|
leafId: string | null;
|
|
131
|
+
/** Latest compact fading state for one checkpoint thread; null clears all. */
|
|
132
|
+
fadingState?: SessionFadingState | null;
|
|
123
133
|
}
|
|
124
134
|
>;
|
|
125
135
|
|
|
@@ -2457,6 +2457,12 @@ export class SubagentExecutor {
|
|
|
2457
2457
|
streamLimits: this.streamLimits,
|
|
2458
2458
|
subagentScope: true,
|
|
2459
2459
|
subagentExecutionContext: childExecutionContext,
|
|
2460
|
+
...(resumeExecution?.graphState.fadingTier == null
|
|
2461
|
+
? {}
|
|
2462
|
+
: { fadingTier: resumeExecution.graphState.fadingTier }),
|
|
2463
|
+
...(resumeExecution?.graphState.fadingTiers == null
|
|
2464
|
+
? {}
|
|
2465
|
+
: { fadingTiers: resumeExecution.graphState.fadingTiers }),
|
|
2460
2466
|
/**
|
|
2461
2467
|
* Forwarded so the child graph's own `SubagentExecutor` (created in
|
|
2462
2468
|
* its `createAgentNode` when `allowNested` keeps subagentConfigs)
|
|
@@ -2,7 +2,13 @@ import type { ToolCall, ToolMessage } from '@langchain/core/messages/tool';
|
|
|
2
2
|
import type { RunnableConfig } from '@langchain/core/runnables';
|
|
3
3
|
import type { ToolOutputReferenceState } from '@/tools/toolOutputReferences';
|
|
4
4
|
import type { ToolApprovalReplaySnapshot } from '@/hooks';
|
|
5
|
-
import type {
|
|
5
|
+
import type {
|
|
6
|
+
FadingTier,
|
|
7
|
+
FadingTiers,
|
|
8
|
+
RunStepResumeState,
|
|
9
|
+
ToolSessionContext,
|
|
10
|
+
} from '@/types';
|
|
11
|
+
import { isFadingTier } from '@/messages/fading';
|
|
6
12
|
import {
|
|
7
13
|
attachRunStepResumeState,
|
|
8
14
|
getRunStepResumeState,
|
|
@@ -65,6 +71,8 @@ export interface SubagentGraphResumeState {
|
|
|
65
71
|
eagerToolSuppressions: string[];
|
|
66
72
|
runStepState?: RunStepResumeState;
|
|
67
73
|
toolOutputReferences?: ToolOutputReferenceState;
|
|
74
|
+
fadingTier?: FadingTier;
|
|
75
|
+
fadingTiers?: FadingTiers;
|
|
68
76
|
}
|
|
69
77
|
|
|
70
78
|
/** Private checkpoint payload linking a parent pause to an exact child state. */
|
|
@@ -301,7 +309,12 @@ function isGraphResumeState(value: unknown): value is SubagentGraphResumeState {
|
|
|
301
309
|
(state.runStepState != null &&
|
|
302
310
|
!isRunStepResumeState(state.runStepState)) ||
|
|
303
311
|
(state.toolOutputReferences != null &&
|
|
304
|
-
!isToolOutputReferenceState(state.toolOutputReferences))
|
|
312
|
+
!isToolOutputReferenceState(state.toolOutputReferences)) ||
|
|
313
|
+
(state.fadingTier != null && !isFadingTier(state.fadingTier)) ||
|
|
314
|
+
(state.fadingTiers != null &&
|
|
315
|
+
(typeof state.fadingTiers !== 'object' ||
|
|
316
|
+
Array.isArray(state.fadingTiers) ||
|
|
317
|
+
!Object.values(state.fadingTiers).every(isFadingTier)))
|
|
305
318
|
) {
|
|
306
319
|
return false;
|
|
307
320
|
}
|
package/src/types/graph.ts
CHANGED
|
@@ -132,6 +132,27 @@ export interface ContextUsageEvent {
|
|
|
132
132
|
calibrationRatio?: number;
|
|
133
133
|
}
|
|
134
134
|
|
|
135
|
+
/**
|
|
136
|
+
* Latched context-fading tier. Caps for historical tool results derive from
|
|
137
|
+
* `(budgetTokens, masked)` only, so carrying the tier across runs keeps their
|
|
138
|
+
* truncated bytes stable for prefix-based provider prompt caches. Hosts
|
|
139
|
+
* persist it beside `calibrationRatio` and pass it back via
|
|
140
|
+
* `RunConfig.fadingTiers[agentId]`.
|
|
141
|
+
*/
|
|
142
|
+
export interface FadingTier {
|
|
143
|
+
v: 1;
|
|
144
|
+
/** Token budget the caps derive from, in raw token space. Never grows;
|
|
145
|
+
* clamped to the current context window when seeded. */
|
|
146
|
+
budgetTokens: number;
|
|
147
|
+
/** Whether observation masking has activated. Never deactivates. */
|
|
148
|
+
masked: boolean;
|
|
149
|
+
/** Whether this tier was reduced, masked, or restored from host state. */
|
|
150
|
+
latched?: true;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/** Latched fading tiers keyed by agent ID. */
|
|
154
|
+
export type FadingTiers = Record<string, FadingTier>;
|
|
155
|
+
|
|
135
156
|
export interface EventHandler {
|
|
136
157
|
handle(
|
|
137
158
|
event: string,
|
|
@@ -346,6 +367,10 @@ export type StandardGraphInput = {
|
|
|
346
367
|
tokenCounter?: TokenCounter;
|
|
347
368
|
indexTokenCountMap?: Record<string, number>;
|
|
348
369
|
calibrationRatio?: number;
|
|
370
|
+
/** Persisted default-agent tier retained for single-agent compatibility. */
|
|
371
|
+
fadingTier?: FadingTier | null;
|
|
372
|
+
/** Persisted fading tiers keyed by agent ID. */
|
|
373
|
+
fadingTiers?: FadingTiers | null;
|
|
349
374
|
/**
|
|
350
375
|
* Receives a {@link SubagentUsageEvent} for every model call that reports
|
|
351
376
|
* usage metadata inside a subagent child run spawned from this graph
|
package/src/types/run.ts
CHANGED
|
@@ -338,6 +338,16 @@ export type RunConfig = {
|
|
|
338
338
|
* conversation. Without this, the EMA resets to 1 on every new Run instance.
|
|
339
339
|
*/
|
|
340
340
|
calibrationRatio?: number;
|
|
341
|
+
/**
|
|
342
|
+
* Default-agent fading tier retained for single-agent compatibility. New
|
|
343
|
+
* multi-agent integrations should use `fadingTiers`.
|
|
344
|
+
*/
|
|
345
|
+
fadingTier?: g.FadingTier | null;
|
|
346
|
+
/**
|
|
347
|
+
* Context-fading tiers keyed by agent ID. Multi-agent hosts should persist
|
|
348
|
+
* the value returned by `Run.getFadingTiers()` and pass it back here.
|
|
349
|
+
*/
|
|
350
|
+
fadingTiers?: g.FadingTiers | null;
|
|
341
351
|
/** Skip post-stream cleanup (clearHeavyState) — useful for tests that inspect graph state after processStream */
|
|
342
352
|
skipCleanup?: boolean;
|
|
343
353
|
/**
|
package/src/utils/errors.ts
CHANGED
|
@@ -219,6 +219,14 @@ const NON_RECOVERABLE_RE =
|
|
|
219
219
|
const OUTPUT_LIMIT_RE =
|
|
220
220
|
/max_?(?:completion_?)?tokens\s*(?:must be|is too|cannot|exceeds|too large|greater than)|maximum number of output tokens|max_tokens.*less than or equal/i;
|
|
221
221
|
|
|
222
|
+
/**
|
|
223
|
+
* A gateway can report this disjunction without saying whether the prompt or
|
|
224
|
+
* requested output caused the rejection. Compaction is unsafe in that case:
|
|
225
|
+
* shrinking a healthy prompt cannot fix an invalid output allowance.
|
|
226
|
+
*/
|
|
227
|
+
const AMBIGUOUS_CONTEXT_OR_OUTPUT_RE =
|
|
228
|
+
/(?:context window[\s\S]{0,80}\bor\b[\s\S]{0,80}max(?:imum)? output|max(?:imum)? output[\s\S]{0,80}\bor\b[\s\S]{0,80}context window)/i;
|
|
229
|
+
|
|
222
230
|
/**
|
|
223
231
|
* Recovers the input-only figure from providers that quote a combined total
|
|
224
232
|
* and then break it down — OpenRouter's "(56811 of text input, 16 in the
|
|
@@ -441,6 +449,10 @@ export function getContextOverflowInfo(
|
|
|
441
449
|
return null;
|
|
442
450
|
}
|
|
443
451
|
|
|
452
|
+
if (AMBIGUOUS_CONTEXT_OR_OUTPUT_RE.test(haystack)) {
|
|
453
|
+
return null;
|
|
454
|
+
}
|
|
455
|
+
|
|
444
456
|
if (OUTPUT_LIMIT_RE.test(haystack)) {
|
|
445
457
|
return null;
|
|
446
458
|
}
|
|
@@ -525,7 +537,11 @@ export function isLikelyContextOverflowError(
|
|
|
525
537
|
return true;
|
|
526
538
|
}
|
|
527
539
|
const haystack = stripUrls(collectErrorText(error));
|
|
528
|
-
if (
|
|
540
|
+
if (
|
|
541
|
+
haystack === '' ||
|
|
542
|
+
AMBIGUOUS_CONTEXT_OR_OUTPUT_RE.test(haystack) ||
|
|
543
|
+
OUTPUT_LIMIT_RE.test(haystack)
|
|
544
|
+
) {
|
|
529
545
|
return false;
|
|
530
546
|
}
|
|
531
547
|
if (NON_RECOVERABLE_RE.test(haystack)) {
|
package/src/utils/truncation.ts
CHANGED
|
@@ -152,3 +152,28 @@ export function truncateToolResultContent(
|
|
|
152
152
|
|
|
153
153
|
return content.slice(0, headEnd) + indicator + content.slice(tailStart);
|
|
154
154
|
}
|
|
155
|
+
|
|
156
|
+
/** Absolute hard cap on a single tool-call input (characters). */
|
|
157
|
+
export const HARD_MAX_TOOL_CALL_INPUT_CHARS = 200_000;
|
|
158
|
+
|
|
159
|
+
/** Smallest JSON value a truncated tool-call input can shrink to. */
|
|
160
|
+
export const MIN_JSON_VALUE_CHARS = 4;
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Computes the max tool-call input size for a context window: 15 % of the
|
|
164
|
+
* window in estimated characters (~4 chars/token), capped at 200K.
|
|
165
|
+
*/
|
|
166
|
+
export function calculateMaxToolCallInputChars(
|
|
167
|
+
maxContextTokens?: number
|
|
168
|
+
): number {
|
|
169
|
+
if (maxContextTokens == null || maxContextTokens <= 0) {
|
|
170
|
+
return HARD_MAX_TOOL_CALL_INPUT_CHARS;
|
|
171
|
+
}
|
|
172
|
+
return Math.max(
|
|
173
|
+
MIN_JSON_VALUE_CHARS,
|
|
174
|
+
Math.min(
|
|
175
|
+
Math.floor(maxContextTokens * 0.15) * 4,
|
|
176
|
+
HARD_MAX_TOOL_CALL_INPUT_CHARS
|
|
177
|
+
)
|
|
178
|
+
);
|
|
179
|
+
}
|