@cerebriline/core 4.100.247 → 4.100.248

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.
@@ -169,6 +169,20 @@ type PrepareTurnResult = {
169
169
  messages?: readonly MessageWithMetadata[];
170
170
  } | undefined;
171
171
  type PrepareTurn = (context: never) => PrepareTurnResult | Promise<PrepareTurnResult>;
172
+ /** A request answered by the conversation itself, or `undefined` to decline. */
173
+ type ConversationAsk = (systemPrompt: string, request: string, maxTokens: number, what: string) => Promise<string | undefined>;
174
+ /**
175
+ * The discarded turn's notes, asked of the conversation as its next turn
176
+ * where that can be done (`DiscardedTurnInput.continueConversation`).
177
+ *
178
+ * Declines -- and the note is asked for in a request of its own, as before --
179
+ * when the runtime offered no way to continue, when a separate summarizer
180
+ * model is configured (it is not the conversation's model), when the provider
181
+ * keeps no prefix to share, and when the instruction and its answer do not fit
182
+ * in what the last request left of the window. A continuation that fails or
183
+ * says nothing declines too: a note is never lost to the attempt.
184
+ */
185
+ export declare function createConversationAsk(input: DiscardedTurnInput, config: CappedThinkingCondenserConfig, providerConfig: ProviderConfig): ConversationAsk | undefined;
172
186
  /**
173
187
  * Condense reasoning that is about to be thrown away rather than sent again.
174
188
  *
@@ -112,6 +112,39 @@ export type MeasureContextTokens = (message: MessageWithMetadata, index: number)
112
112
  * the context as it stands, which is the question the reservation is asking.
113
113
  */
114
114
  export declare function resolveObservedOutputTokens(messages: readonly MessageWithMetadata[], measure: MeasureContextTokens, sampleTurns?: number): number | undefined;
115
+ /**
116
+ * What a compaction written as the conversation's next turn needs on top of
117
+ * the conversation: its instruction and its summary.
118
+ *
119
+ * One function because two things ask it. The trigger asks before the fact,
120
+ * so that compaction starts while this still fits; the continuation asks at
121
+ * the moment it would start, and steps aside when it does not. Harness run
122
+ * 0432 (2026-10-11) is what two different answers cost: the trigger waited
123
+ * for 90% of an 85,106-token window, the writer's request then measured
124
+ * 92,738, and each such compaction fell back to a summary that did not fit
125
+ * beside the conversation either, released the conversation's window and made
126
+ * the next turn read its whole prompt again.
127
+ */
128
+ export declare const CONTINUATION_WRITER_INSTRUCTION_TOKENS = 3072;
129
+ export declare function resolveContinuationWriterRoomTokens(contextWindow: number | undefined): number;
130
+ /**
131
+ * What the conversation has gained since its last request was measured: the
132
+ * newest assistant message and the results that followed it.
133
+ *
134
+ * The provider's count is of the request that produced that message, so it
135
+ * holds neither. In run 0432 the count was 78,895 and the conversation the
136
+ * writer had to continue was about 90,000.
137
+ */
138
+ export declare function resolvePendingTurnTokens(messages: readonly MessageWithMetadata[], measure: MeasureContextTokens): number;
139
+ /**
140
+ * How much one turn adds to the conversation, from this session's own turns:
141
+ * an assistant message and everything up to the next one.
142
+ *
143
+ * Read the way {@link resolveObservedOutputTokens} reads output, for the same
144
+ * reason: the newest turns count in full, and past them a single large turn is
145
+ * an outlier and the second largest sets the figure.
146
+ */
147
+ export declare function resolveObservedTurnGrowthTokens(messages: readonly MessageWithMetadata[], measure: MeasureContextTokens, sampleTurns?: number): number | undefined;
115
148
  /**
116
149
  * The largest prompt that still leaves the model room to answer.
117
150
  *
@@ -150,6 +183,19 @@ export declare function resolveCompactionTriggerTokens(input: {
150
183
  modelMaxTokens?: number;
151
184
  /** The high-water output of recent turns, from {@link resolveObservedOutputTokens}. */
152
185
  observedOutputTokens?: number;
186
+ /**
187
+ * Set where compaction would be written as the conversation's next turn.
188
+ * The trigger then also holds back what that turn needs, so compaction
189
+ * starts while it still fits: the writer's own room, what the conversation
190
+ * has gained since the count the trigger compares was taken, and one more
191
+ * turn like this session's.
192
+ */
193
+ continuation?: {
194
+ /** {@link resolvePendingTurnTokens}; 0 when the compared count is current. */
195
+ pendingTokens: number;
196
+ /** {@link resolveObservedTurnGrowthTokens}. */
197
+ turnGrowthTokens?: number;
198
+ };
153
199
  }): number;
154
200
  export interface FileOperationSummary {
155
201
  readFiles: string[];
@@ -186,6 +186,12 @@ export interface CompactionContinuation {
186
186
  * where the engine books.
187
187
  */
188
188
  fresh(purpose: "retrospective" | "synthesizer", systemPrompt: string, request: string, maxTokens: number, providerConfig: ProviderConfig, reservation?: PPrimeReservation): Promise<ContinuationCallResult>;
189
+ /**
190
+ * Whether a retrospective of about `chars` characters would run as the
191
+ * session's own next turn. It has to be asked for before {@link release}
192
+ * then: afterwards there is no session to continue.
193
+ */
194
+ retrospectiveFitsInSession(chars: number, maxTokens: number): boolean;
189
195
  /**
190
196
  * Give the session's cells back: the critics, P', P, then the session's
191
197
  * own slot. Idempotent; run before the synthesizer, and again by
@@ -216,6 +222,12 @@ export interface PrepareContinuationInput {
216
222
  requestTokens: number;
217
223
  /** The last request's own prompt count, when one was measured. */
218
224
  observedRequestTokens?: number;
225
+ /**
226
+ * What the conversation has gained since `requestTokens` was counted: the
227
+ * newest assistant message and the results after it. 0 when the count is
228
+ * an estimate of the conversation as it stands.
229
+ */
230
+ pendingTokens?: number;
219
231
  reasoning: ContinuationReasoning;
220
232
  /** A summarizer model of its own is configured: it cannot continue this one. */
221
233
  separateSummarizer: boolean;
@@ -238,6 +250,12 @@ export interface PrepareContinuationInput {
238
250
  }
239
251
  /** Whether a failed call is the server saying "not now". */
240
252
  export declare function isInfraFault(error: unknown): boolean;
253
+ /**
254
+ * Why compaction on this connection is never written as a continuation, or
255
+ * `undefined` when it can be. The part of the answer that does not depend on
256
+ * the turn, so the trigger can ask it before there is a compaction to prepare.
257
+ */
258
+ export declare function continuationCompactionExcluded(config: ProviderConfig, separateSummarizer: boolean): string | undefined;
241
259
  /**
242
260
  * Whether compaction on this connection can run as a continuation, and in
243
261
  * which shape. `undefined` continuation with the reason when it cannot.
@@ -61,6 +61,19 @@ export declare class HubCommandError extends Error {
61
61
  }
62
62
  export declare function isHubCommandTimeoutError(error: unknown, command?: HubCommandEnvelope["command"]): boolean;
63
63
  export declare function rememberRecoverableLocalHubUrl(url: string, authToken?: string): string;
64
+ /**
65
+ * Keep a local hub's token for the connections this process makes to it,
66
+ * without marking the hub as one this process may restart.
67
+ *
68
+ * A hub on an explicit endpoint (`CLINE_HUB_PORT`, or a host/port the caller
69
+ * passed) is not "recoverable", and that used to mean its token was not kept
70
+ * either. The caller that had just started it got back a URL, connected with
71
+ * no token and was refused: "WebSocket connection to
72
+ * 'ws://127.0.0.1:25499/hub' failed: Connection ended", on every first start
73
+ * (solidPC and eleven2go, 2026-10-11, three of three). The second start
74
+ * worked because it found the discovery record, which carries the token.
75
+ */
76
+ export declare function rememberLocalHubAuthToken(url: string, authToken?: string): void;
64
77
  export declare class NodeHubClient {
65
78
  private readonly options;
66
79
  private socket;