@modelprofile.com/flexharness 14.0.0 → 16.0.0
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_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/classes.flexharness.cachewarm.d.ts +2 -2
- package/dist_ts/classes.flexharness.cachewarm.js +1 -1
- package/dist_ts/classes.flexharness.core.d.ts +8 -1
- package/dist_ts/classes.flexharness.core.js +44 -31
- package/dist_ts/classes.flexharness.d.ts +5 -4
- package/dist_ts/classes.flexharness.js +10 -7
- package/dist_ts/classes.flexharness.prompts.d.ts +9 -5
- package/dist_ts/classes.flexharness.prompts.js +93 -18
- package/dist_ts/classes.flexharness.runs.d.ts +9 -4
- package/dist_ts/classes.flexharness.runs.js +70 -18
- package/dist_ts/classes.flexharness.sessions.d.ts +4 -5
- package/dist_ts/classes.flexharness.sessions.js +45 -12
- package/dist_ts/classes.flexharness.subagents.js +1 -1
- package/dist_ts/errors.d.ts +9 -0
- package/dist_ts/errors.js +14 -1
- package/dist_ts/index.d.ts +2 -0
- package/dist_ts/index.js +2 -1
- package/dist_ts/interfaces.d.ts +119 -11
- package/dist_ts/interfaces.flexharness.d.ts +12 -8
- package/dist_ts/interfaces.js +1 -1
- package/dist_ts/plugins.d.ts +3 -3
- package/dist_ts/plugins.js +3 -3
- package/dist_ts/utils.harnessoptions.js +6 -3
- package/dist_ts/utils.json.js +74 -18
- package/dist_ts/utils.sessionmetrics.d.ts +12 -1
- package/dist_ts/utils.sessionmetrics.js +18 -1
- package/dist_ts/utils.transfer.js +14 -1
- package/dist_ts/utils.validation.d.ts +7 -2
- package/dist_ts/utils.validation.js +28 -7
- package/package.json +3 -3
- package/readme.md +75 -6
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/classes.flexharness.cachewarm.ts +2 -2
- package/ts/classes.flexharness.core.ts +49 -30
- package/ts/classes.flexharness.prompts.ts +124 -39
- package/ts/classes.flexharness.runs.ts +78 -24
- package/ts/classes.flexharness.sessions.ts +54 -9
- package/ts/classes.flexharness.subagents.ts +2 -1
- package/ts/classes.flexharness.ts +25 -5
- package/ts/errors.ts +15 -0
- package/ts/index.ts +6 -0
- package/ts/interfaces.flexharness.ts +12 -8
- package/ts/interfaces.ts +125 -11
- package/ts/plugins.ts +13 -0
- package/ts/readme.md +75 -6
- package/ts/utils.harnessoptions.ts +9 -2
- package/ts/utils.json.ts +75 -18
- package/ts/utils.sessionmetrics.ts +23 -0
- package/ts/utils.transfer.ts +13 -0
- package/ts/utils.validation.ts +31 -5
package/ts/interfaces.ts
CHANGED
|
@@ -92,8 +92,36 @@ export interface IFlexSessionMetricsState {
|
|
|
92
92
|
reportedLifetimeCacheWriteTokens?: number;
|
|
93
93
|
/** The breakdown counts every call since the session began, without saturation. */
|
|
94
94
|
lifetimeTokenBreakdownComplete?: boolean;
|
|
95
|
+
/** The served context window of the last settled run's model; see `IFlexSessionMetrics`. */
|
|
96
|
+
contextWindow?: number;
|
|
97
|
+
/** The last settled run's compaction point; exclusive with `contextCompactionOff`. */
|
|
98
|
+
contextCompactionTokens?: number;
|
|
99
|
+
/** Why the last settled run had no compaction point; exclusive with `contextCompactionTokens`. */
|
|
100
|
+
contextCompactionOff?: TFlexContextCompactionOff;
|
|
95
101
|
}
|
|
96
102
|
|
|
103
|
+
/**
|
|
104
|
+
* A session's choice of its proactive compaction point, in tokens of the model in use.
|
|
105
|
+
*
|
|
106
|
+
* - `{ tokens }`: a positive integer, clamped at run time to the ceiling of the run's model (90%
|
|
107
|
+
* of its served context window). Without a known served window it applies unclamped.
|
|
108
|
+
* - `{ percent }`: an integer from 1 through 90 of the served window. Without a known served
|
|
109
|
+
* window the run has no proactive compaction.
|
|
110
|
+
* - `false`: no proactive compaction.
|
|
111
|
+
*
|
|
112
|
+
* Omitted, the model's default applies: the catalog's automatic compaction point
|
|
113
|
+
* (`IFlexResolvedModel.contextCompactionDefaultTokens`) when stated, at most the ceiling,
|
|
114
|
+
* otherwise the ceiling itself.
|
|
115
|
+
*/
|
|
116
|
+
export type TFlexContextCompactionSetting = plugins.TAgentContextCompactionSetting;
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Why a run had no proactive compaction point: the setting is `false` (`disabled`), the run's
|
|
120
|
+
* model states no served context window and the setting needs one (`no-context-window`), or the
|
|
121
|
+
* harness has no `contextCompactor` (`no-compactor`).
|
|
122
|
+
*/
|
|
123
|
+
export type TFlexContextCompactionOff = plugins.TAgentContextCompactionOff | 'no-compactor';
|
|
124
|
+
|
|
97
125
|
/** No member estimates current context size or includes child-session / tool-owned model calls. */
|
|
98
126
|
export interface IFlexSessionMetrics {
|
|
99
127
|
/** Sum of durably settled per-call reports; a lower bound when incomplete. */
|
|
@@ -120,6 +148,19 @@ export interface IFlexSessionMetrics {
|
|
|
120
148
|
* the session's calls were counted by input and cache since it began.
|
|
121
149
|
*/
|
|
122
150
|
lifetimeTokenBreakdownComplete: boolean;
|
|
151
|
+
/**
|
|
152
|
+
* The served context window, in tokens, of the model the last settled run resolved; absent when
|
|
153
|
+
* that model states none or before the first run.
|
|
154
|
+
*/
|
|
155
|
+
contextWindow?: number;
|
|
156
|
+
/**
|
|
157
|
+
* The proactive compaction point the last settled run used, in tokens. Exactly one of it and
|
|
158
|
+
* `contextCompactionOff` is present once a run settled; neither before. A changed session
|
|
159
|
+
* setting shows from the next run; `resolveAgentContextCompactionPoint` states it before.
|
|
160
|
+
*/
|
|
161
|
+
contextCompactionTokens?: number;
|
|
162
|
+
/** Why the last settled run had no proactive compaction point. */
|
|
163
|
+
contextCompactionOff?: TFlexContextCompactionOff;
|
|
123
164
|
}
|
|
124
165
|
|
|
125
166
|
export interface IFlexModelIdentity {
|
|
@@ -222,6 +263,21 @@ export interface IFlexMessage {
|
|
|
222
263
|
rejectedPermissionId?: string;
|
|
223
264
|
/** On a user message that steered its running run: the caller's steer identity. */
|
|
224
265
|
steerId?: string;
|
|
266
|
+
/** On the user message that heads a run: the caller's prompt identity, when the prompt named one. */
|
|
267
|
+
promptId?: string;
|
|
268
|
+
/**
|
|
269
|
+
* On a user message, once its run reached its terminal state: whether the run's result kept this
|
|
270
|
+
* message in the model context of later turns, the value the run's `keptInContext` reports. It
|
|
271
|
+
* records that outcome and is never rewritten afterwards: an undo is reported by `undone`, and a
|
|
272
|
+
* later compaction summarizes the message, which was still delivered. Absent on a message whose
|
|
273
|
+
* run has not ended, and on messages written before FlexHarness 15.0.0.
|
|
274
|
+
*/
|
|
275
|
+
keptInContext?: boolean;
|
|
276
|
+
/**
|
|
277
|
+
* Set only by a read with `includeUndone`: the message belongs to an undone turn that a redo can
|
|
278
|
+
* bring back. Never stored.
|
|
279
|
+
*/
|
|
280
|
+
undone?: true;
|
|
225
281
|
/**
|
|
226
282
|
* On both messages of a cache-warm turn: the harness sent the prompt only to keep the model's
|
|
227
283
|
* prompt cache warm. Hosts leave these out of what they show and report as work.
|
|
@@ -268,6 +324,8 @@ export interface IFlexSession {
|
|
|
268
324
|
depth?: number;
|
|
269
325
|
/** Set only on a session the staged session import created; such a session is read-only. */
|
|
270
326
|
origin?: IFlexSessionOrigin;
|
|
327
|
+
/** The session's compaction setting; absent for the harness default. */
|
|
328
|
+
contextCompaction?: TFlexContextCompactionSetting;
|
|
271
329
|
}
|
|
272
330
|
|
|
273
331
|
/** The position of an imported session when one source conversation was split into several sessions. */
|
|
@@ -394,14 +452,25 @@ export interface IFlexCreateSessionOptions {
|
|
|
394
452
|
sessionGenerationId?: string;
|
|
395
453
|
configurationRef?: string;
|
|
396
454
|
title?: string;
|
|
455
|
+
/** The session's compaction setting; omitted for the harness default. */
|
|
456
|
+
contextCompaction?: TFlexContextCompactionSetting;
|
|
397
457
|
}
|
|
398
458
|
|
|
399
459
|
export interface IFlexUpdateSessionOptions {
|
|
400
460
|
title?: string | null;
|
|
401
461
|
archived?: boolean;
|
|
462
|
+
/** The session's compaction setting; `null` returns the session to the harness default. */
|
|
463
|
+
contextCompaction?: TFlexContextCompactionSetting | null;
|
|
402
464
|
}
|
|
403
465
|
|
|
404
466
|
export interface IFlexPromptOptions {
|
|
467
|
+
/**
|
|
468
|
+
* The caller's identity for this prompt, a non-empty string of at most 512 UTF-8 bytes. It is on
|
|
469
|
+
* the prompt's queue entry and on the user message that heads its run, so a caller can tell
|
|
470
|
+
* exactly whether the prompt was taken in. An outstanding prompt of the session holding the same
|
|
471
|
+
* id rejects the admission with `FlexHarnessDuplicatePromptError`.
|
|
472
|
+
*/
|
|
473
|
+
promptId?: string;
|
|
405
474
|
modelHint?: string;
|
|
406
475
|
system?: string;
|
|
407
476
|
/** Optional positive safe integer step cap; no limit unless configured. */
|
|
@@ -528,7 +597,11 @@ export interface IFlexPromptQueueEntry {
|
|
|
528
597
|
status: TFlexPromptQueueStatus;
|
|
529
598
|
queuedAt: string;
|
|
530
599
|
runId?: string;
|
|
600
|
+
/** The prompt's `promptId`, when it named one. */
|
|
601
|
+
promptId?: string;
|
|
531
602
|
scheduleKey?: string;
|
|
603
|
+
/** This entry answers existing context without adding a prompt message. */
|
|
604
|
+
continuation?: true;
|
|
532
605
|
/** The entry is a cache-warm prompt; see {@link IFlexMessage.cacheWarm}. */
|
|
533
606
|
cacheWarm?: true;
|
|
534
607
|
startedAt?: string;
|
|
@@ -537,8 +610,9 @@ export interface IFlexPromptQueueEntry {
|
|
|
537
610
|
/**
|
|
538
611
|
* On a finished entry: whether its prompt, the steers its run took in and what its model
|
|
539
612
|
* produced stay in the model context of later turns. True for a completed run and a run
|
|
540
|
-
* stopped after its model produced output; false for
|
|
541
|
-
* model output and a prompt that never ran.
|
|
613
|
+
* stopped or failed after its model produced output; false for an unsuccessful run without
|
|
614
|
+
* model output and a prompt that never ran. For a continuation, this describes only the new
|
|
615
|
+
* run's history; it does not change the retention of the existing input.
|
|
542
616
|
*/
|
|
543
617
|
keptInContext?: boolean;
|
|
544
618
|
/**
|
|
@@ -549,10 +623,10 @@ export interface IFlexPromptQueueEntry {
|
|
|
549
623
|
unappliedSteerIds?: string[];
|
|
550
624
|
}
|
|
551
625
|
|
|
552
|
-
|
|
626
|
+
/** The result of answering existing context, without adding a prompt message. */
|
|
627
|
+
export interface IFlexContinuePromptResult {
|
|
553
628
|
runId: string;
|
|
554
629
|
sessionId: string;
|
|
555
|
-
userMessage: IFlexMessage;
|
|
556
630
|
/** The run's last assistant message; a steered run completed earlier ones as it took steers in. */
|
|
557
631
|
assistantMessage: IFlexMessage;
|
|
558
632
|
model: IFlexModelIdentity;
|
|
@@ -563,6 +637,10 @@ export interface IFlexPromptResult {
|
|
|
563
637
|
unappliedSteerIds: string[];
|
|
564
638
|
}
|
|
565
639
|
|
|
640
|
+
export interface IFlexPromptResult extends IFlexContinuePromptResult {
|
|
641
|
+
userMessage: IFlexMessage;
|
|
642
|
+
}
|
|
643
|
+
|
|
566
644
|
/** A message for the running run of a session, taken in at the run's next step boundary. */
|
|
567
645
|
export interface IFlexSteerInput {
|
|
568
646
|
/** Caller-chosen identity, unique among the steers of the run. */
|
|
@@ -576,12 +654,13 @@ export interface IFlexSteerAdmission {
|
|
|
576
654
|
runId: string;
|
|
577
655
|
}
|
|
578
656
|
|
|
579
|
-
export interface IFlexPromptQueueAdmission {
|
|
657
|
+
export interface IFlexPromptQueueAdmission<TResult extends IFlexContinuePromptResult = IFlexPromptResult> {
|
|
580
658
|
queueId: string;
|
|
581
|
-
completion: Promise<
|
|
659
|
+
completion: Promise<TResult>;
|
|
582
660
|
}
|
|
583
661
|
|
|
584
|
-
export interface IFlexPromptAdmission extends
|
|
662
|
+
export interface IFlexPromptAdmission<TResult extends IFlexContinuePromptResult = IFlexPromptResult>
|
|
663
|
+
extends IFlexPromptQueueAdmission<TResult> {
|
|
585
664
|
runId: string;
|
|
586
665
|
}
|
|
587
666
|
|
|
@@ -602,11 +681,27 @@ export interface IFlexEnqueuePromptOptions extends IFlexPromptOptions {
|
|
|
602
681
|
steers?: readonly IFlexSteerInput[];
|
|
603
682
|
}
|
|
604
683
|
|
|
684
|
+
/** Options for continuation through the same FIFO, optionally with scheduled execution. */
|
|
685
|
+
export interface IFlexContinuePromptOptions extends Omit<IFlexEnqueuePromptOptions, 'promptId'> {
|
|
686
|
+
scheduleKey?: string;
|
|
687
|
+
/** Requires scheduleKey; defaults to 50 ms when scheduled. */
|
|
688
|
+
debounceMs?: number;
|
|
689
|
+
}
|
|
690
|
+
|
|
605
691
|
export interface IFlexScheduledPromptAdmission extends IFlexPromptAdmission {
|
|
606
692
|
scheduleKey: string;
|
|
607
693
|
}
|
|
608
694
|
|
|
609
|
-
|
|
695
|
+
/** Options of the transcript reads. */
|
|
696
|
+
export interface IFlexMessageReadOptions {
|
|
697
|
+
/**
|
|
698
|
+
* Also return the messages of undone turns, each marked `undone: true`, in their place after the
|
|
699
|
+
* visible ones. Messages a committed branch removed are gone and never returned.
|
|
700
|
+
*/
|
|
701
|
+
includeUndone?: boolean;
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
export interface IFlexMessagePageOptions extends IFlexMessageReadOptions {
|
|
610
705
|
limit?: number;
|
|
611
706
|
before?: string;
|
|
612
707
|
}
|
|
@@ -669,6 +764,19 @@ export interface IFlexResolvedModel {
|
|
|
669
764
|
cache?: TFlexAgentCacheSetting;
|
|
670
765
|
/** Optional positive safe integer step cap; no limit unless configured. */
|
|
671
766
|
maxSteps?: number;
|
|
767
|
+
/**
|
|
768
|
+
* The model's served context window in tokens, from the provider's catalog: the window the
|
|
769
|
+
* provider serves by default, never an extended maximum (for a Codex catalog `context_window`,
|
|
770
|
+
* not `max_context_window`; for Anthropic's Models API `max_input_tokens`). Omitted when the
|
|
771
|
+
* catalog states none: the run then has a compaction point only from a `{ tokens }` setting.
|
|
772
|
+
*/
|
|
773
|
+
contextWindow?: number;
|
|
774
|
+
/**
|
|
775
|
+
* The catalog's own automatic compaction point in tokens, when it states one (a Codex catalog's
|
|
776
|
+
* `auto_compact_token_limit`). It lowers the default point, never the ceiling. Requires
|
|
777
|
+
* `contextWindow`.
|
|
778
|
+
*/
|
|
779
|
+
contextCompactionDefaultTokens?: number;
|
|
672
780
|
}
|
|
673
781
|
|
|
674
782
|
export interface IFlexModelResolver<TScope> {
|
|
@@ -1167,7 +1275,8 @@ export interface IFlexScopeSnapshot {
|
|
|
1167
1275
|
export interface IFlexTerminalProjection {
|
|
1168
1276
|
runId: string;
|
|
1169
1277
|
status: 'completed' | 'failed' | 'cancelled';
|
|
1170
|
-
|
|
1278
|
+
/** Absent for a continuation, which creates no prompt message. */
|
|
1279
|
+
userMessage?: IFlexMessage;
|
|
1171
1280
|
assistantMessage: IFlexMessage;
|
|
1172
1281
|
model?: IFlexModelIdentity;
|
|
1173
1282
|
/** The usage the provider reported for the run's model calls, whatever the status. */
|
|
@@ -1195,7 +1304,8 @@ export interface IFlexAffectedWorkspace {
|
|
|
1195
1304
|
|
|
1196
1305
|
interface IFlexReversionSegmentV2 {
|
|
1197
1306
|
runId: string;
|
|
1198
|
-
|
|
1307
|
+
/** Absent for an assistant-only continuation segment. */
|
|
1308
|
+
userMessageId?: string;
|
|
1199
1309
|
status: TFlexReversionSegmentStatus;
|
|
1200
1310
|
contextAvailable: boolean;
|
|
1201
1311
|
eventIds: string[];
|
|
@@ -1891,7 +2001,11 @@ export type TFlexAgentContextCompactor<TScope = unknown> = (
|
|
|
1891
2001
|
export interface IFlexAgentSessionPolicy<TScope = unknown> {
|
|
1892
2002
|
contextBuilder?: plugins.TAgentContextBuilder;
|
|
1893
2003
|
contextCompactor?: TFlexAgentContextCompactor<TScope>;
|
|
1894
|
-
|
|
2004
|
+
/**
|
|
2005
|
+
* The harness default compaction setting, for sessions without their own. Omitted, the model's
|
|
2006
|
+
* default applies. Requires `contextCompactor` unless `false`.
|
|
2007
|
+
*/
|
|
2008
|
+
contextCompaction?: TFlexContextCompactionSetting;
|
|
1895
2009
|
eventRetention?: TFlexAgentSessionOptions['eventRetention'];
|
|
1896
2010
|
changeListenerTimeoutMs?: number;
|
|
1897
2011
|
maxPendingSessionChanges?: number;
|
package/ts/plugins.ts
CHANGED
|
@@ -92,6 +92,7 @@ export const importCodeSandboxEngine = async (): Promise<ICodeSandboxEngine> =>
|
|
|
92
92
|
|
|
93
93
|
// @push.rocks scope
|
|
94
94
|
import {
|
|
95
|
+
AGENT_CONTEXT_COMPACTION_CEILING_PERCENT,
|
|
95
96
|
AgentEventStoreConflictError,
|
|
96
97
|
AgentPendingInputQueue,
|
|
97
98
|
applyAgentEventChange,
|
|
@@ -100,13 +101,16 @@ import {
|
|
|
100
101
|
AgentPendingInputRejectedError,
|
|
101
102
|
AgentSession,
|
|
102
103
|
AgentToolCallScheduler,
|
|
104
|
+
assertAgentContextCompactionSetting,
|
|
103
105
|
buildModelMessages,
|
|
106
|
+
getAgentContextCompactionCeiling,
|
|
104
107
|
ToolJobStoreConflictError,
|
|
105
108
|
createAgentEvent,
|
|
106
109
|
filterModelVisibleAgentEvents,
|
|
107
110
|
getAgentGenerationTransactions,
|
|
108
111
|
isGenerationInModelContext,
|
|
109
112
|
modelMessagesToAgentEvents,
|
|
113
|
+
resolveAgentContextCompactionPoint,
|
|
110
114
|
tool,
|
|
111
115
|
validateAgentEventArchive,
|
|
112
116
|
validateAgentEventSnapshot,
|
|
@@ -114,6 +118,7 @@ import {
|
|
|
114
118
|
} from '@modelprofile.com/flexharness-agent';
|
|
115
119
|
|
|
116
120
|
export {
|
|
121
|
+
AGENT_CONTEXT_COMPACTION_CEILING_PERCENT,
|
|
117
122
|
AgentEventStoreConflictError,
|
|
118
123
|
AgentPendingInputQueue,
|
|
119
124
|
applyAgentEventChange,
|
|
@@ -122,13 +127,16 @@ export {
|
|
|
122
127
|
AgentPendingInputRejectedError,
|
|
123
128
|
AgentSession,
|
|
124
129
|
AgentToolCallScheduler,
|
|
130
|
+
assertAgentContextCompactionSetting,
|
|
125
131
|
buildModelMessages,
|
|
132
|
+
getAgentContextCompactionCeiling,
|
|
126
133
|
ToolJobStoreConflictError,
|
|
127
134
|
createAgentEvent,
|
|
128
135
|
filterModelVisibleAgentEvents,
|
|
129
136
|
getAgentGenerationTransactions,
|
|
130
137
|
isGenerationInModelContext,
|
|
131
138
|
modelMessagesToAgentEvents,
|
|
139
|
+
resolveAgentContextCompactionPoint,
|
|
132
140
|
tool,
|
|
133
141
|
validateAgentEventArchive,
|
|
134
142
|
validateAgentEventSnapshot,
|
|
@@ -141,6 +149,7 @@ export type {
|
|
|
141
149
|
TSmartAiCacheBudgetBasis,
|
|
142
150
|
IAgentEventArchive,
|
|
143
151
|
IAgentEventChange,
|
|
152
|
+
IAgentContextCompactionInput,
|
|
144
153
|
IAgentContextCompactionOptions,
|
|
145
154
|
IAgentEventSnapshot,
|
|
146
155
|
IAgentEventStore,
|
|
@@ -150,6 +159,7 @@ export type {
|
|
|
150
159
|
IAgentRetryEvent,
|
|
151
160
|
IAgentRunResult,
|
|
152
161
|
IAgentSession,
|
|
162
|
+
IAgentContinuationSession,
|
|
153
163
|
IAgentSessionOptions,
|
|
154
164
|
IAgentToolCallUpdateEvent,
|
|
155
165
|
IAgentToolExecutionOptions,
|
|
@@ -165,6 +175,9 @@ export type {
|
|
|
165
175
|
IToolJobStore,
|
|
166
176
|
IToolPermissionRequest,
|
|
167
177
|
TAgentContextBuilder,
|
|
178
|
+
TAgentContextCompactionOff,
|
|
179
|
+
TAgentContextCompactionPoint,
|
|
180
|
+
TAgentContextCompactionSetting,
|
|
168
181
|
TAgentContextCompactor,
|
|
169
182
|
TAgentEvent,
|
|
170
183
|
TAgentGenerationOutcome,
|
package/ts/readme.md
CHANGED
|
@@ -111,6 +111,9 @@ A warm read joins outstanding projection writes and surfaces accounting failures
|
|
|
111
111
|
| `lastObservedInputTokensFreshness` | Always `historical`. This is **not** current context size: output, steering, compaction and reversion can change context. |
|
|
112
112
|
| `reportedLifetimeInputTokens` | Sum of the settled per-call reports' input tokens, prompt-cache reads included. |
|
|
113
113
|
| `reportedLifetimeCacheReadTokens`, `reportedLifetimeCacheWriteTokens` | Sums of the settled per-call reports' input tokens read from and written to the prompt cache. |
|
|
114
|
+
| `contextWindow` | The served context window, in tokens, of the model the last settled run resolved; absent when that model states none. |
|
|
115
|
+
| `contextCompactionTokens` | The compaction point the last settled run used, in tokens. |
|
|
116
|
+
| `contextCompactionOff` | Why the last settled run had no compaction point: `disabled`, `no-context-window` or `no-compactor`. Exactly one of it and `contextCompactionTokens` is present once a run settled. |
|
|
114
117
|
| `lifetimeTokenBreakdownComplete` | The three sums cover every call `lifetimeUsedTokens` covers: lifetime usage is complete and the session's calls were counted by input and cache since it began. Otherwise they are lower bounds. |
|
|
115
118
|
|
|
116
119
|
Accounting covers this session's generation calls and reported compaction calls,
|
|
@@ -495,7 +498,7 @@ Sending requires the exact active parent run, its currently delegated direct chi
|
|
|
495
498
|
|
|
496
499
|
Before creating or resuming a child, FlexHarness requests permission on the parent run with `kind: 'subagent.start'`, the parent `toolCallId`, and separately bounded harness-owned agent/task metadata. Its metadata includes `childSessionId`, the exact ID reserved for this call: FlexHarness derives it deterministically when `taskId` is omitted and copies the supplied candidate when `taskId` is present. A resume also retains that candidate as `taskId`. This block is not truncated by `toolOutputLimits`. The reserved ID binds permission handling before child creation but does not prove that the child exists or is owned: applications must treat the later delegated admission context as authoritative. The controller answers through the normal permission APIs. This request has no `rememberKey`, so `always` is invalid; controllers use `once` or `reject`.
|
|
497
500
|
|
|
498
|
-
Each new invocation creates a durable child `IFlexSession` with immutable `parentSessionId`, origin `parentRunId`, origin `parentToolCallId`, `agent`, and `depth`. New public roots persist `depth: 0`; legacy schema-1 roots may omit it. These fields are harness-owned; public `createSession()` accepts `sessionId`, `sessionGenerationId`, `configurationRef`, and `title`. A child inherits its parent's `configurationRef` and cannot resume under a different reference. Child sessions reject direct `prompt()`, `startPrompt()`, `enqueuePrompt()`, and `schedulePrompt()` calls and run only through the `delegate` tool. The model and tool resolver contexts receive optional immutable `parentSessionId` and `agent` values so integrations can apply agent-specific model and tool policy. Child prompts use the definition's `modelHint`, `system`, and `maxSteps`.
|
|
501
|
+
Each new invocation creates a durable child `IFlexSession` with immutable `parentSessionId`, origin `parentRunId`, origin `parentToolCallId`, `agent`, and `depth`. New public roots persist `depth: 0`; legacy schema-1 roots may omit it. These fields are harness-owned; public `createSession()` accepts `sessionId`, `sessionGenerationId`, `configurationRef`, and `title`. A child inherits its parent's `configurationRef` and cannot resume under a different reference. Child sessions reject direct `continuePrompt()`, `prompt()`, `startPrompt()`, `enqueuePrompt()`, and `schedulePrompt()` calls and run only through the `delegate` tool. The model and tool resolver contexts receive optional immutable `parentSessionId` and `agent` values so integrations can apply agent-specific model and tool policy. Child prompts use the definition's `modelHint`, `system`, and `maxSteps`.
|
|
499
502
|
|
|
500
503
|
The parent tool part receives `childSessionId` as soon as the child is acquired, so a host can offer an authorized live transcript. A foreground call also adds the resolved child model to its part and returns bounded JSON:
|
|
501
504
|
|
|
@@ -706,7 +709,7 @@ Queue payloads, status records, and `prompt.*` queue events are process-local. T
|
|
|
706
709
|
|
|
707
710
|
The reservation save is the admission point. A save failure produces no start events or active audit. If disposal begins while that save is in flight and the save commits, admission still resolves and its completion settles as cancelled; disposal waits for terminal finalization.
|
|
708
711
|
|
|
709
|
-
`listMessagePage()` returns the newest contiguous page in chronological order. `limit` must be an integer from 1 through 50 and defaults to 50. `nextCursor` is opaque, limited to 4096 UTF-8 bytes, bound to the resolved storage namespace and session, and remains stable when newer messages are appended. Mismatched and stale cursors fail validation. Each page carries `startIndex`, the zero-based index of its first message in the session's visible history (for an empty page, the index the page ends at), so a consumer can order and page by absolute position. Appending messages leaves every index unchanged; a branch after an undo reuses the positions of the history it replaces, so a consumer re-reads its pages after `session.history.changed`. `getMessage()` performs an exact lookup. Transfer identifiers are limited to 512 bytes, text and reasoning parts to 96 KiB, complete messages to 480 KiB, and complete page envelopes to 512 KiB. A page may therefore contain fewer messages than requested. Oversized text is truncated and an otherwise oversized parts collection is replaced with an explicit elision marker; metadata that still cannot fit fails validation. Canonical private Agent events are unchanged.
|
|
712
|
+
`listMessagePage()` returns the newest contiguous page in chronological order. `limit` must be an integer from 1 through 50 and defaults to 50. `nextCursor` is opaque, limited to 4096 UTF-8 bytes, bound to the resolved storage namespace and session, and remains stable when newer messages are appended. Mismatched and stale cursors fail validation. Each page carries `startIndex`, the zero-based index of its first message in the session's visible history (for an empty page, the index the page ends at), so a consumer can order and page by absolute position. Appending messages leaves every index unchanged; a branch after an undo reuses the positions of the history it replaces, so a consumer re-reads its pages after `session.history.changed`. `getMessage()` performs an exact lookup. `getMessages()`, `listMessagePage()`, `getMessage()` and `getSessionView()` take `includeUndone: true` to also return the messages of undone turns, which a redo can bring back: they follow the visible messages in their place, each marked `undone: true`, and page indexes count them. `undone` is set only by such a read and never stored. Messages a committed branch removed are gone and no read returns them. Transfer identifiers are limited to 512 bytes, text and reasoning parts to 96 KiB, complete messages to 480 KiB, and complete page envelopes to 512 KiB. A page may therefore contain fewer messages than requested. Oversized text is truncated and an otherwise oversized parts collection is replaced with an explicit elision marker; metadata that still cannot fit fails validation. Canonical private Agent events are unchanged.
|
|
710
713
|
|
|
711
714
|
`updateSession()` supports title replacement, explicit title clearing with `null`, and archive state through `archived`. Title-only updates remain available while prompts are queued or running, while permission is pending, and after archival. Requests containing `archived` are rejected while the session has any outstanding prompt or pending permission; a mixed title-and-archive request is rejected atomically without changing the title. Archived sessions expose `archivedAt`. Every session exposes `preview` once a run with prompt text was admitted: its first prompt as one line (whitespace runs collapsed, cut at a character boundary to `maxTitleBytes`), with no model call, so a host can name a session nobody titled (`title || preview`). It is set once, a session stored before previews existed takes it from its first prompt at its next run, and no caller sets or clears it. Deleting a session cascades through its complete descendant subtree. One durable root-keyed tombstone group hides every newly affected live session, and the delete also joins any already-separate descendant cleanup groups without rewriting their roots. FlexHarness then cancels queued and active subtree work, emits terminal queue events, waits for admitted initialization, and purges runtime queue status while cleaning runtime and persisted domains child-first. The requested root tombstone is removed last after every domain confirms cleanup; project-management cleanup confirmation is a retained durable project tombstone rather than physical removal. An imported session can hold no project-management state, so its deletion writes no project tombstone. A successful live `deleteSession()` call emits `session.deleted` for each session it newly tombstoned; retries of an existing tombstone and automatic load, retirement, or disposal cleanup emit no deletion events. Direct deletion of a descendant cascades only through that descendant's subtree. Cleanup authority follows the resolved storage namespace, so scope aliases share the same groups. A partial failure retains durable ownership for retry by a later `deleteSession()`, namespace load, `retireScope()`, or `dispose()` call.
|
|
712
715
|
|
|
@@ -714,6 +717,55 @@ The reservation save is the admission point. A save failure produces no start ev
|
|
|
714
717
|
|
|
715
718
|
`abort()` returns `true` only while cancellation is still accepted. Terminal persistence is the run's commit point; once it starts, `abort()` returns `false` and the already-fixed terminal outcome completes while the session remains busy.
|
|
716
719
|
|
|
720
|
+
### Continuing Without New Input
|
|
721
|
+
|
|
722
|
+
Use `continuePrompt()` after a failed or stopped run whose input remains in context
|
|
723
|
+
(`keptInContext: true`), when the conversation still needs an answer:
|
|
724
|
+
|
|
725
|
+
```typescript
|
|
726
|
+
const continuation = await harness.continuePrompt(scopeId, sessionId, {
|
|
727
|
+
modelHint: 'available-model',
|
|
728
|
+
});
|
|
729
|
+
console.log(continuation.queueId);
|
|
730
|
+
const result = await continuation.completion;
|
|
731
|
+
console.log(result.assistantMessage.parts);
|
|
732
|
+
```
|
|
733
|
+
|
|
734
|
+
The signature is `continuePrompt(scopeId: string, sessionId: string,
|
|
735
|
+
options?: IFlexContinuePromptOptions): Promise<IFlexPromptQueueAdmission<IFlexContinuePromptResult>>`.
|
|
736
|
+
It accepts `modelHint`, `system`, `maxSteps` and initial `steers`, plus optional
|
|
737
|
+
`scheduleKey` and `debounceMs` for the same scheduling behavior as `schedulePrompt()`.
|
|
738
|
+
`debounceMs` requires a schedule key and defaults to 50 ms when scheduled. There is
|
|
739
|
+
no `prompt` or `promptId`: continuation creates a new run and an assistant message
|
|
740
|
+
without appending or modifying a user message. Its result has the prompt result's
|
|
741
|
+
fields except `userMessage`. Explicit steers still become user messages normally.
|
|
742
|
+
|
|
743
|
+
Admission returns `{ queueId, completion }` once queued, like `enqueuePrompt()`.
|
|
744
|
+
The entry and its `prompt.*` events carry `continuation: true`. Inspect its `runId`
|
|
745
|
+
after `prompt.started`, or read it through `getPromptQueueEntry()`. Use the same
|
|
746
|
+
`cancelPrompt()`, `cancelScheduledPrompt()`, `abort()` and `steerPrompt()` methods.
|
|
747
|
+
Queue bounds and FIFO order, permissions, resource cleanup, compaction, usage
|
|
748
|
+
accounting and provider limits follow the ordinary run path.
|
|
749
|
+
|
|
750
|
+
At the front of the FIFO, the harness validates the visible transcript and model
|
|
751
|
+
context with undone and excluded runs filtered out, before committing an undone
|
|
752
|
+
branch or reserving a generation or audit message. A refusal preserves redo history.
|
|
753
|
+
Empty context, an already answered turn, and an unsuccessful input that did not stay
|
|
754
|
+
in context refuse with `FlexHarnessValidationError` through `completion`. A retained
|
|
755
|
+
failure whose model context ends in partial assistant text with no tool call is also
|
|
756
|
+
refused; `keptInContext: true` alone does not guarantee it can be continued. An earlier
|
|
757
|
+
queued answer can therefore invalidate a waiting continuation. Cancellation before
|
|
758
|
+
execution leaves the retained input available for another continuation. Continuing never replays
|
|
759
|
+
previous tool calls; unknown external effects still require reconciliation.
|
|
760
|
+
|
|
761
|
+
Existing projections and Agent event stores remain readable without migration.
|
|
762
|
+
Assistant-only runs require two optional fields in the existing schema-3 projection:
|
|
763
|
+
a staged terminal omits `userMessage`, and its reversion segment omits
|
|
764
|
+
`userMessageId`. Requiring either would invent a user message. Generation claims
|
|
765
|
+
use existing events without a new `user-message` event. Older strict projection
|
|
766
|
+
readers cannot open a session containing these continuation records; do not mix
|
|
767
|
+
versions or downgrade those sessions.
|
|
768
|
+
|
|
717
769
|
### Steering a Running Turn
|
|
718
770
|
|
|
719
771
|
`steerPrompt()` hands a message to the running run of a prompt instead of queueing it behind that run:
|
|
@@ -734,6 +786,8 @@ The run takes a steer in at its next step boundary: after the tool results of it
|
|
|
734
786
|
|
|
735
787
|
A prompt can bring further user messages into its run: `startPrompt()`, `enqueuePrompt()` and `prompt()` take `steers`, a list of `{ steerId, prompt }`, in their options. The run accepts them when it starts, emitting `prompt.steer.accepted` for each in the given order right after `prompt.started`, and takes them in before its first model call, so the model sees the prompt and its steers as consecutive user messages of their own in one call, each with its own `steerId`, `messageId` and attachments. From then on they report like every other steer of the run. They count against the session's outstanding prompt limits from admission on. The whole prompt is refused with `FlexHarnessValidationError` when a `steerId` repeats, and with `FlexHarnessQueueFullError` when it brings more steers than `maxOutstandingPromptsPerSession` or its steers' bytes exceed the outstanding byte limit. A prompt cancelled before its run started lists them in `unappliedSteerIds` on its finished queue entry and `prompt.finished`, with `keptInContext: false`. A caller holding several waiting messages for a session delivers them in one turn this way, without merging them into one message.
|
|
736
788
|
|
|
789
|
+
A prompt can name itself with `promptId` in its options (`startPrompt()`, `enqueuePrompt()`, `prompt()` and `schedulePrompt()`): a non-empty string of at most 512 UTF-8 bytes, validated like a `steerId`. It is on the prompt's queue entry and its queue events, and on the user message that heads its run, also after a restart, so a caller that is unsure whether a prompt was taken in finds out from the transcript. A prompt whose `promptId` an outstanding prompt of the same session, queued or running, already holds is refused with `FlexHarnessDuplicatePromptError`; once that prompt finished, the id is free again. Other sessions' prompts do not count.
|
|
790
|
+
|
|
737
791
|
### Keeping the Prompt Cache Warm
|
|
738
792
|
|
|
739
793
|
A provider's prompt cache expires when nothing reads it for its TTL, and the next turn then writes the whole prefix again. `keepCacheWarm()` keeps a root session's cache warm until a deadline:
|
|
@@ -812,7 +866,7 @@ At most 128 custom commands may be registered. Every registration must be a plai
|
|
|
812
866
|
|
|
813
867
|
`/undo` and `/redo`, plus `undoSession()` and `redoSession()`, move a durable history cursor. The direct methods return `{ revertedRunId }` and `{ restoredRunId }`; the slash forms return `{ type: 'operation', name: 'undo' | 'redo' }`. Each committed cursor move emits one `session.history.changed` event with `direction`, `runId`, and the selected session identity. A committed branch emits the same event with `direction: 'branch'` and no `runId`, so controllers should refresh the complete selected session. Capture finalization, cleanup, and metadata-only changes do not emit this event.
|
|
814
868
|
|
|
815
|
-
A completed root-session turn defines an operation-group boundary. Failed and cancelled turns after it belong to that group; leading failed or cancelled turns belong to the first completed group. No completed boundary means there is nothing to undo; retained leading unsuccessful history is grouped with the next completed turn rather than silently discarded. Undo hides that group's canonical partial history and outcome markers as well as its visible messages, redo restores them, and branching keeps the hidden history excluded. Transcript-only undo never claims to reverse external tool effects. Undo applies selected segments in reverse order and redo applies them in forward order. Without `turnReversionProvider`, only transcript and future model context move. Hidden messages disappear from `getMessages()`, message pages, exact message lookup, and future model context. Starting a new prompt, template, handler, or compaction from an undone position commits a branch: hidden messages and segments are removed durably and cannot be redone. Successful event archival also commits hidden redo history; a missing compaction or failed archive leaves it intact. Automatic budget compaction archives covered events after generation finalization and advances the same undo horizon;
|
|
869
|
+
A completed root-session turn defines an operation-group boundary. Failed and cancelled turns after it belong to that group; leading failed or cancelled turns belong to the first completed group. No completed boundary means there is nothing to undo; retained leading unsuccessful history is grouped with the next completed turn rather than silently discarded. Undo hides that group's canonical partial history and outcome markers as well as its visible messages, redo restores them, and branching keeps the hidden history excluded. Transcript-only undo never claims to reverse external tool effects. Undo applies selected segments in reverse order and redo applies them in forward order. Without `turnReversionProvider`, only transcript and future model context move. Hidden messages disappear from `getMessages()`, message pages, exact message lookup, and future model context. Starting a new prompt, template, handler, or compaction from an undone position commits a branch: hidden messages and segments are removed durably and cannot be redone. Successful event archival also commits hidden redo history; a missing compaction or failed archive leaves it intact. Automatic budget compaction archives covered events after generation finalization and advances the same undo horizon; `contextCompaction: false` turns budget compaction off.
|
|
816
870
|
|
|
817
871
|
Two horizons bound undo. Retention pruning removes the oldest complete visible units when `reversionLimits` is exceeded. Explicit event archival marks covered turns context-unavailable and prunes complete prefixes that can no longer be rebuilt; FlexHarness never crosses that archive horizon. Manual compaction without archival retains the original events and remains undoable. Schema-1 projection history and sessions migrated from `2.x` have no reversion segments, so historical turns are not retroactively undoable; newly written turns are tracked normally.
|
|
818
872
|
|
|
@@ -950,7 +1004,7 @@ The model context is built by the session's canonical AgentSession event history
|
|
|
950
1004
|
2. The normalized current user message.
|
|
951
1005
|
3. AgentSession's result messages.
|
|
952
1006
|
|
|
953
|
-
A failed or cancelled prompt remains visible through `getMessages()` with its truthful `failed` or `cancelled` status. Its canonical partial history also remains in future model context when execution produced output; an unsuccessful generation without output is omitted. Retention is not acceptance and does not roll back or replay external effects. Canonical Agent events remain private and are not exposed by the session or message APIs.
|
|
1007
|
+
A failed or cancelled prompt remains visible through `getMessages()` with its truthful `failed` or `cancelled` status. Its canonical partial history also remains in future model context when execution produced output; an unsuccessful generation without output is omitted. Each user message, the prompt and every steer its run took in, carries `keptInContext` once its run reached its terminal state: the run's `keptInContext`, true when the run's result kept the message in the model context of later turns, false when it did not, as for an unsuccessful run without model or tool output; a failed or stopped run that produced output stays in context and reports true. It records that outcome and is never rewritten: a later undo is reported by `undone` on an `includeUndone` read, and a later compaction summarizes the message, which was still delivered. A message whose run has not ended carries none, and neither do messages written before FlexHarness 15.0.0. Retention is not acceptance and does not roll back or replay external effects. Canonical Agent events remain private and are not exposed by the session or message APIs.
|
|
954
1008
|
|
|
955
1009
|
Resolved model identity contains provider and model IDs plus optional display name and effective `variant`. The identity, including its variant, is attached to a failed assistant message when resolution completed before a later failure, matching the provider/model behavior. Prompt results contain it only on success.
|
|
956
1010
|
|
|
@@ -1005,7 +1059,7 @@ if (started.status === 'started') {
|
|
|
1005
1059
|
|
|
1006
1060
|
**Read-only.** An imported session never runs, and nothing writes model context for it: it has no Agent events and no tool jobs. Every operation that would change its history or model context throws `FlexHarnessImportedSessionError` (code `FLEX_SESSION_READ_ONLY`):
|
|
1007
1061
|
|
|
1008
|
-
- `prompt`, `startPrompt`, `enqueuePrompt` and `
|
|
1062
|
+
- `prompt`, `startPrompt`, `enqueuePrompt`, `schedulePrompt` and `continuePrompt`;
|
|
1009
1063
|
- `executeSlashCommand` and `compactSession`;
|
|
1010
1064
|
- `undoSession` and `redoSession`;
|
|
1011
1065
|
- `pushRuntimeEvent`, `reconcileToolExecution` and `archiveSessionEvents`;
|
|
@@ -1082,6 +1136,21 @@ Transactional tool calls persist an execution intent before the tool side effect
|
|
|
1082
1136
|
|
|
1083
1137
|
`executionContextProvider` can construct a AgentSession execution context for each session. FlexHarness supplies the resolved scope, storage key, and the session's private job store. The public background APIs expose only execution ID, type, state, exit code, and timestamps; command payloads, stdout, and stderr remain private. The provider's optional `close()` is owned by session deletion, scope retirement, and harness disposal.
|
|
1084
1138
|
|
|
1139
|
+
### Compaction Point
|
|
1140
|
+
|
|
1141
|
+
With a compactor, a generation compacts settled history before its first inference once the session's context reaches its compaction point, in tokens of the run's model. The point never exceeds its ceiling: 90% of the model's served context window, which the model resolver states as `IFlexResolvedModel.contextWindow`. That is the window the provider serves by default, never an extended maximum: a Codex catalog's `context_window`, not its `max_context_window`; Anthropic's Models API `max_input_tokens`, where 1M is the default window of the 1M-token models without any beta header. By default the point is the ceiling, or the catalog's own automatic compaction point when it states a lower one (`IFlexResolvedModel.contextCompactionDefaultTokens`, a Codex catalog's `auto_compact_token_limit`). A session chooses its own point with `contextCompaction` on `createSession()` or `updateSession()`, where `null` returns it to the default; `agentSessionPolicy.contextCompaction` is the default for sessions without one.
|
|
1142
|
+
|
|
1143
|
+
| `contextCompaction` | Compaction point |
|
|
1144
|
+
| --- | --- |
|
|
1145
|
+
| omitted | The model's default; none when the model states no served window |
|
|
1146
|
+
| `{ tokens }` | The count, clamped at run time to the ceiling of the run's model; unclamped when the model states no served window |
|
|
1147
|
+
| `{ percent }` | An integer from 1 through 90 of the served window; none when the model states none |
|
|
1148
|
+
| `false` | None |
|
|
1149
|
+
|
|
1150
|
+
A percent outside 1 through 90, a token count that is not a positive integer, or a setting other than `false` on a harness without a `contextCompactor` is rejected with `FlexHarnessValidationError`. `getSessionMetrics()` states the last settled run's `contextWindow` and either its `contextCompactionTokens` or, when it had none, `contextCompactionOff`: `disabled`, `no-context-window` or `no-compactor`. A changed setting shows there from the next run; `resolveAgentContextCompactionPoint({ contextWindow, contextCompactionDefaultTokens, setting })` states the point a session would have on a model before any run.
|
|
1151
|
+
|
|
1152
|
+
The context is measured with the provider's own count where there is one. Each transactional generation's outcome event carries `contextUsage`: the input tokens its last model call reported, with the events that call saw. The reading counts while those events still build the same model messages and no compaction followed them; what was committed after it is estimated at 4 UTF-8 JSON bytes per token. After a compaction, an undo or a branch, and for history written before readings existed, the whole context is estimated that way. The check runs once per generation, before its first inference: a generation that grows past the point in its own tool loop is compacted only when its context overflows.
|
|
1153
|
+
|
|
1085
1154
|
### Context Compaction Model
|
|
1086
1155
|
|
|
1087
1156
|
A `contextCompactor` states which model to compact with from the model the compacted work was dispatched on, never from a host default that may name another account:
|
|
@@ -1089,7 +1158,7 @@ A `contextCompactor` states which model to compact with from the model the compa
|
|
|
1089
1158
|
| `reason` | Compaction | Model members |
|
|
1090
1159
|
| --- | --- | --- |
|
|
1091
1160
|
| `context-overflow` | A run's context overflowed, including a delegated run's | `resolvedModel`: the `IFlexResolvedModel` the model resolver returned for that run, frozen; a delegated run's overflow carries the delegated run's own model |
|
|
1092
|
-
| `context-budget` |
|
|
1161
|
+
| `context-budget` | The context reaches the session's compaction point before a generation's first inference; see Compaction Point | `resolvedModel`: the exact model resolved for that run, including its delegated model |
|
|
1093
1162
|
| `manual` | `/compact` or `compactSession()` | `modelHint`: the `modelHint` of the `/compact` execution options or of `compactSession(scopeId, sessionId, { modelHint })`, when one was passed |
|
|
1094
1163
|
| `retention` | Event retention | none |
|
|
1095
1164
|
|
|
@@ -33,7 +33,7 @@ import {
|
|
|
33
33
|
isReservedSlashCommandName,
|
|
34
34
|
isValidSlashCommandName,
|
|
35
35
|
} from './utils.slashcommands.js';
|
|
36
|
-
import { validateUtf8String } from './utils.validation.js';
|
|
36
|
+
import { validateContextCompactionSetting, validateUtf8String } from './utils.validation.js';
|
|
37
37
|
|
|
38
38
|
export type TRegisteredSlashCommand<TScope> =
|
|
39
39
|
| Readonly<IFlexSlashCommandTemplateRegistration>
|
|
@@ -548,10 +548,17 @@ export function resolveResultLimits(
|
|
|
548
548
|
export function normalizeAgentSessionPolicy<TScope>(
|
|
549
549
|
policy: IFlexAgentSessionPolicy<TScope> = {},
|
|
550
550
|
): IFlexAgentSessionPolicy<TScope> {
|
|
551
|
+
if (policy.contextCompaction !== undefined) {
|
|
552
|
+
validateContextCompactionSetting(
|
|
553
|
+
policy.contextCompaction,
|
|
554
|
+
policy.contextCompactor !== undefined,
|
|
555
|
+
'agentSessionPolicy.contextCompaction',
|
|
556
|
+
);
|
|
557
|
+
}
|
|
551
558
|
return {
|
|
552
559
|
...(policy.contextBuilder === undefined ? {} : { contextBuilder: policy.contextBuilder }),
|
|
553
560
|
...(policy.contextCompactor === undefined ? {} : { contextCompactor: policy.contextCompactor }),
|
|
554
|
-
...(policy.
|
|
561
|
+
...(policy.contextCompaction === undefined ? {} : { contextCompaction: policy.contextCompaction }),
|
|
555
562
|
...(policy.eventRetention === undefined ? {} : { eventRetention: policy.eventRetention }),
|
|
556
563
|
...(policy.changeListenerTimeoutMs === undefined
|
|
557
564
|
? {}
|