Skip to content

Commit 43173a0

Browse files
committed
Avoid hard-coded string detection for "full" notebooks in favor of a boolean flag
1 parent 26334a5 commit 43173a0

File tree

1 file changed

+21
-15
lines changed

1 file changed

+21
-15
lines changed

extensions/positron-assistant/src/tools/notebookUtils.ts

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,8 @@ export interface SerializedNotebookContext {
250250
contextNote: string;
251251
/** Full wrapped context (if wrapInNotebookContext is true) */
252252
fullContext?: string;
253+
/** Whether this serialized context represents a full notebook (true) or a windowed context (false). Undefined when allCellsInfo is not present. */
254+
isFullNotebookContext?: boolean;
253255
}
254256

255257
/**
@@ -272,6 +274,13 @@ export function serializeNotebookContext(
272274
// Get all cells from context (may already be filtered)
273275
const allCells = context.allCells || [];
274276
const totalCells = context.cellCount;
277+
const canIncludeFullNotebook = totalCells < MAX_CELLS_FOR_ALL_CELLS_CONTEXT;
278+
279+
// Helper function to find executed cells (used in multiple places)
280+
const getExecutedCells = (cells: positron.notebooks.NotebookCell[]) => {
281+
const codeCells = cells.filter(c => c.type === positron.notebooks.NotebookCellType.Code);
282+
return codeCells.filter(c => c.executionOrder !== undefined);
283+
};
275284

276285
// Determine anchor index for sliding window if not provided
277286
let effectiveAnchorIndex: number;
@@ -282,8 +291,7 @@ export function serializeNotebookContext(
282291
effectiveAnchorIndex = Math.max(...context.selectedCells.map(cell => cell.index));
283292
} else {
284293
// Try to find last executed cell
285-
const codeCells = allCells.filter(c => c.type === positron.notebooks.NotebookCellType.Code);
286-
const executedCells = codeCells.filter(c => c.executionOrder !== undefined);
294+
const executedCells = getExecutedCells(allCells);
287295
if (executedCells.length > 0) {
288296
effectiveAnchorIndex = Math.max(...executedCells.map(c => c.index));
289297
} else {
@@ -295,21 +303,20 @@ export function serializeNotebookContext(
295303
// Apply filtering logic to determine which cells to include
296304
let cellsToInclude: positron.notebooks.NotebookCell[];
297305

298-
if (totalCells < MAX_CELLS_FOR_ALL_CELLS_CONTEXT) {
306+
if (canIncludeFullNotebook) {
299307
// Small notebooks: include all cells
300308
cellsToInclude = allCells.length > 0 ? allCells : [];
301309
} else if (context.selectedCells.length === 0 && allCells.length === 0) {
302310
// Large notebooks without selection and no allCells: no cells to include
303311
cellsToInclude = [];
304312
} else if (context.selectedCells.length === 0) {
305313
// Large notebooks without selection: use sliding window around executed cells
306-
const codeCells = allCells.filter(c => c.type === positron.notebooks.NotebookCellType.Code);
307-
const executedCells = codeCells.filter(c => c.executionOrder !== undefined);
314+
const executedCells = getExecutedCells(allCells);
308315
if (executedCells.length > 0 || effectiveAnchorIndex !== 0) {
309316
const { startIndex, endIndex } = calculateSlidingWindow(allCells.length, effectiveAnchorIndex);
310317
cellsToInclude = allCells.slice(startIndex, endIndex);
311318
} else {
312-
// No executed cells, use first 20 cells
319+
// No executed cells, use first MAX_CELLS_FOR_ALL_CELLS_CONTEXT cells
313320
cellsToInclude = allCells.slice(0, MAX_CELLS_FOR_ALL_CELLS_CONTEXT);
314321
}
315322
} else {
@@ -344,8 +351,7 @@ export function serializeNotebookContext(
344351
let allCellsInfo: string | undefined;
345352
let formattedCells: string | undefined;
346353
if (cellsToInclude.length > 0) {
347-
const isFullNotebook = context.cellCount < 20;
348-
const description = isFullNotebook
354+
const description = canIncludeFullNotebook
349355
? 'All cells in notebook (notebook has fewer than 20 cells)'
350356
: 'Context window around selected/recent cells (notebook has 20+ cells)';
351357
// Format cells once and reuse
@@ -358,7 +364,7 @@ export function serializeNotebookContext(
358364
// Generate context note XML
359365
let contextNote: string;
360366
if (cellsToInclude.length > 0) {
361-
if (context.cellCount < 20) {
367+
if (canIncludeFullNotebook) {
362368
contextNote = xml.node('note', 'All cells are provided above because this notebook has fewer than 20 cells.');
363369
} else {
364370
contextNote = xml.node('note', 'A context window around the selected/recent cells is provided above. Use the GetNotebookCells tool to retrieve additional cells by index when needed.');
@@ -373,13 +379,13 @@ export function serializeNotebookContext(
373379
cellCountInfo,
374380
selectedCellsInfo,
375381
allCellsInfo,
376-
contextNote
382+
contextNote,
383+
isFullNotebookContext: allCellsInfo ? canIncludeFullNotebook : undefined
377384
};
378385

379386
// Optionally wrap in notebook-context node
380387
if (wrapInNotebookContext) {
381-
const isFullNotebook = context.cellCount < 20;
382-
const contextMode = isFullNotebook
388+
const contextMode = canIncludeFullNotebook
383389
? 'Full notebook (< 20 cells, all cells provided below)'
384390
: 'Context window around selected/recent cells (notebook has 20+ cells)';
385391

@@ -601,9 +607,9 @@ export function serializeNotebookContextAsUserMessage(
601607

602608
// Determine context mode based on whether allCellsInfo exists
603609
if (context.allCellsInfo) {
604-
// Check if this is a full notebook or windowed context by examining the allCellsInfo
605-
const isFullNotebook = context.allCellsInfo.includes('fewer than 20 cells');
606-
const contextMode = isFullNotebook
610+
// Use explicit isFullNotebookContext field instead of parsing XML
611+
const isFullNotebookContext = context.isFullNotebookContext === true;
612+
const contextMode = isFullNotebookContext
607613
? 'Full notebook (< 20 cells, all cells provided below)'
608614
: 'Context window around selected/recent cells (notebook has 20+ cells)';
609615
parts.push(xml.node('context-mode', contextMode));

0 commit comments

Comments
 (0)