@juspay/neurolink 12.30.2 → 12.31.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/CHANGELOG.md +3 -2
- package/dist/browser/neurolink.min.js +399 -382
- package/dist/cli/loop/optionsSchema.d.ts +1 -1
- package/dist/cli/proxy-clients/codex.js +21 -16
- package/dist/core/baseProvider.js +1 -0
- package/dist/core/modules/MessageBuilder.js +10 -0
- package/dist/neurolink.js +1 -0
- package/dist/processors/document/ExcelProcessor.d.ts +13 -1
- package/dist/processors/document/ExcelProcessor.js +118 -0
- package/dist/processors/document/WordProcessor.js +21 -0
- package/dist/proxy/proxyHistoryTruncation.js +28 -7
- package/dist/types/file.d.ts +15 -0
- package/dist/types/generate.d.ts +11 -1
- package/dist/types/processor.d.ts +11 -0
- package/dist/types/stream.d.ts +6 -1
- package/dist/types/utilities.d.ts +19 -0
- package/dist/utils/fileDetector.js +31 -36
- package/dist/utils/htmlToMarkdown.d.ts +23 -0
- package/dist/utils/htmlToMarkdown.js +442 -0
- package/dist/utils/messageBuilder.js +3 -0
- package/dist/utils/multimodalOptionsBuilder.d.ts +3 -0
- package/dist/utils/multimodalOptionsBuilder.js +6 -0
- package/docs-site/static/search-index.json +5 -1
- package/package.json +2 -1
|
@@ -4,4 +4,4 @@ import type { OptionSchema, TextGenerationOptions } from "../../types/index.js";
|
|
|
4
4
|
* This object provides metadata for validation and help text in the CLI loop.
|
|
5
5
|
* It is derived from the main TextGenerationOptions interface to ensure consistency.
|
|
6
6
|
*/
|
|
7
|
-
export declare const textGenerationOptionsSchema: Record<keyof Omit<TextGenerationOptions, "prompt" | "input" | "schema" | "tools" | "context" | "conversationHistory" | "conversationMessages" | "conversationMemoryConfig" | "originalPrompt" | "middleware" | "expectedOutcome" | "evaluationCriteria" | "region" | "csvOptions" | "pdfOptions" | "imageOptions" | "videoOptions" | "tts" | "stt" | "thinkingConfig" | "requestId" | "fileRegistry" | "abortSignal" | "toolFilter" | "excludeTools" | "toolChoice" | "prepareStep" | "credentials" | "onFinish" | "onError" | "processors" | "piiDetection" | "responseValidation" | "inputValidation" | "toolExecutionCapture" | "toolExecutionRecorder" | "toolRoots">, OptionSchema>;
|
|
7
|
+
export declare const textGenerationOptionsSchema: Record<keyof Omit<TextGenerationOptions, "prompt" | "input" | "schema" | "tools" | "context" | "conversationHistory" | "conversationMessages" | "conversationMemoryConfig" | "originalPrompt" | "middleware" | "expectedOutcome" | "evaluationCriteria" | "region" | "csvOptions" | "pdfOptions" | "imageOptions" | "videoOptions" | "officeOptions" | "tts" | "stt" | "thinkingConfig" | "requestId" | "fileRegistry" | "abortSignal" | "toolFilter" | "excludeTools" | "toolChoice" | "prepareStep" | "credentials" | "onFinish" | "onError" | "processors" | "piiDetection" | "responseValidation" | "inputValidation" | "toolExecutionCapture" | "toolExecutionRecorder" | "toolRoots">, OptionSchema>;
|
|
@@ -158,23 +158,28 @@ export async function setCodexProxySettings(baseUrl) {
|
|
|
158
158
|
logger.warn(`[proxy] Codex: config.toml declares [${duplicate}] more than once; leaving it untouched`);
|
|
159
159
|
return false;
|
|
160
160
|
}
|
|
161
|
-
//
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
161
|
+
// Same preamble boundary the edit paths use. Matching document-wide would
|
|
162
|
+
// capture a `model_provider` belonging to a table — a legacy
|
|
163
|
+
// `[profiles.<name>]` block, say — and the restore would then write that
|
|
164
|
+
// profile's provider back as the top-level selector.
|
|
165
|
+
let providerMatch = null;
|
|
166
|
+
editTomlPreamble(original, (preamble) => {
|
|
167
|
+
providerMatch = preamble.match(CODEX_PROVIDER_LINE_RE);
|
|
168
|
+
return null;
|
|
169
|
+
});
|
|
170
|
+
// A selector naming "neurolink" is the one the proxy writes, possibly left
|
|
171
|
+
// by an earlier run, and never the user's choice.
|
|
172
|
+
const userProviderLine = providerMatch && !/"neurolink"/.test(providerMatch[0])
|
|
173
|
+
? providerMatch[0]
|
|
174
|
+
: null;
|
|
175
|
+
const selectorIsOurs = providerMatch !== null && userProviderLine === null;
|
|
176
|
+
// Snapshot on first touch, and again whenever the top-level selector is
|
|
177
|
+
// not the proxy's. An unclean exit skips restore and leaves the snapshot
|
|
178
|
+
// behind; a provider the user then picks by hand, or a selector they
|
|
179
|
+
// remove, is newer than that snapshot and is what restore must bring back.
|
|
180
|
+
if (!fs.existsSync(getCodexSnapshotPath()) || !selectorIsOurs) {
|
|
176
181
|
fs.mkdirSync(join(homedir(), ".neurolink"), { recursive: true });
|
|
177
|
-
await writeFileAtomic(getCodexSnapshotPath(), JSON.stringify({ originalProviderLine }, null, 2), 0o600);
|
|
182
|
+
await writeFileAtomic(getCodexSnapshotPath(), JSON.stringify({ originalProviderLine: userProviderLine }, null, 2), 0o600);
|
|
178
183
|
}
|
|
179
184
|
// Every proxy start applies. Rewriting a file that already matches only
|
|
180
185
|
// widens the window for racing Codex's own saves.
|
|
@@ -937,6 +937,7 @@ export class BaseProvider {
|
|
|
937
937
|
csvOptions: options.csvOptions,
|
|
938
938
|
pdfOptions: options.pdfOptions,
|
|
939
939
|
videoOptions: options.videoOptions,
|
|
940
|
+
officeOptions: options.officeOptions,
|
|
940
941
|
// Forward abort, tool filtering, and timeout options to prevent
|
|
941
942
|
// silent bypass when falling back from real streaming to fake streaming
|
|
942
943
|
abortSignal: options.abortSignal,
|
|
@@ -109,6 +109,11 @@ export class MessageBuilder {
|
|
|
109
109
|
// transcription flag are read downstream by the detector, and
|
|
110
110
|
// a reconstruction that omits them silently restores defaults.
|
|
111
111
|
videoOptions: options.videoOptions,
|
|
112
|
+
// This object is rebuilt field by field, so anything not named
|
|
113
|
+
// here never reaches the multimodal builder — the same way
|
|
114
|
+
// audioFiles/videoFiles went missing in #284. Office options
|
|
115
|
+
// steer XLSX sheet selection and rendering.
|
|
116
|
+
officeOptions: options.officeOptions,
|
|
112
117
|
provider: options.provider,
|
|
113
118
|
model: options.model,
|
|
114
119
|
temperature: options.temperature,
|
|
@@ -244,6 +249,11 @@ export class MessageBuilder {
|
|
|
244
249
|
// transcription flag are read downstream by the detector, and
|
|
245
250
|
// a reconstruction that omits them silently restores defaults.
|
|
246
251
|
videoOptions: options.videoOptions,
|
|
252
|
+
// This object is rebuilt field by field, so anything not named
|
|
253
|
+
// here never reaches the multimodal builder — the same way
|
|
254
|
+
// audioFiles/videoFiles went missing in #284. Office options
|
|
255
|
+
// steer XLSX sheet selection and rendering.
|
|
256
|
+
officeOptions: options.officeOptions,
|
|
247
257
|
provider: options.provider,
|
|
248
258
|
model: options.model,
|
|
249
259
|
temperature: options.temperature,
|
package/dist/neurolink.js
CHANGED
|
@@ -4284,6 +4284,7 @@ Current user's request: ${currentInput}`;
|
|
|
4284
4284
|
// caller's video settings have ever reached a provider -- frames and
|
|
4285
4285
|
// quality included, not just the native-video flags added alongside.
|
|
4286
4286
|
videoOptions: options.videoOptions,
|
|
4287
|
+
officeOptions: options.officeOptions,
|
|
4287
4288
|
region: options.region,
|
|
4288
4289
|
tts: options.tts,
|
|
4289
4290
|
stt: options.stt,
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
* ```
|
|
37
37
|
*/
|
|
38
38
|
import { BaseFileProcessor } from "../base/BaseFileProcessor.js";
|
|
39
|
-
import type { FileInfo, ProcessOptions, ProcessedExcel, ProcessorFileProcessingResult } from "../../types/index.js";
|
|
39
|
+
import type { ExcelWorksheet, FileInfo, OfficeProcessorOptions, ProcessOptions, ProcessedExcel, ProcessorFileProcessingResult } from "../../types/index.js";
|
|
40
40
|
/**
|
|
41
41
|
* Excel Processor - handles .xlsx and .xls files.
|
|
42
42
|
* Uses exceljs library for parsing with support for large files.
|
|
@@ -136,6 +136,18 @@ export declare class ExcelProcessor extends BaseFileProcessor<ProcessedExcel> {
|
|
|
136
136
|
*/
|
|
137
137
|
extractSheetRange(buffer: Buffer, sheet?: string | number, rowStart?: number, rowEnd?: number, columns?: string[]): Promise<string>;
|
|
138
138
|
}
|
|
139
|
+
/**
|
|
140
|
+
* Render processed worksheets into the text handed to the model.
|
|
141
|
+
*
|
|
142
|
+
* @param worksheets - Worksheets extracted from the workbook
|
|
143
|
+
* @param totalRows - Total row count across all extracted worksheets
|
|
144
|
+
* @param options - Office options; `sheetName` selects a single sheet and
|
|
145
|
+
* `formatStyle` chooses the rendering (default `raw`, the tab-separated
|
|
146
|
+
* preview that predates the option)
|
|
147
|
+
* @returns Prompt-ready text, or a message naming the available sheets when
|
|
148
|
+
* `sheetName` matches none of them
|
|
149
|
+
*/
|
|
150
|
+
export declare function formatWorksheetsForPrompt(worksheets: ExcelWorksheet[], totalRows: number, options?: OfficeProcessorOptions): string;
|
|
139
151
|
/**
|
|
140
152
|
* Singleton Excel processor instance.
|
|
141
153
|
* Use this for standard Excel processing operations.
|
|
@@ -39,6 +39,7 @@ import { BaseFileProcessor } from "../base/BaseFileProcessor.js";
|
|
|
39
39
|
import { SIZE_LIMITS } from "../config/index.js";
|
|
40
40
|
import { FileErrorCode } from "../errors/index.js";
|
|
41
41
|
import { tryImport } from "../../utils/tryImport.js";
|
|
42
|
+
import { dedupeColumnNames } from "../../utils/csvProcessor.js";
|
|
42
43
|
let _exceljs = null;
|
|
43
44
|
async function loadExcelJS() {
|
|
44
45
|
if (_exceljs) {
|
|
@@ -482,6 +483,123 @@ export class ExcelProcessor extends BaseFileProcessor {
|
|
|
482
483
|
}
|
|
483
484
|
}
|
|
484
485
|
// =============================================================================
|
|
486
|
+
// PROMPT FORMATTING
|
|
487
|
+
// =============================================================================
|
|
488
|
+
/** Rows beyond this per sheet are summarised rather than listed. */
|
|
489
|
+
const PROMPT_PREVIEW_ROWS = 20;
|
|
490
|
+
/** RFC 4180: quote a field that contains a comma, quote or newline. */
|
|
491
|
+
function csvEscape(value) {
|
|
492
|
+
return /[",\r\n]/.test(value) ? `"${value.replace(/"/g, '""')}"` : value;
|
|
493
|
+
}
|
|
494
|
+
/** A pipe inside a cell would otherwise split it into two columns. */
|
|
495
|
+
function markdownEscape(value) {
|
|
496
|
+
return value
|
|
497
|
+
.replace(/\\/g, "\\\\")
|
|
498
|
+
.replace(/\|/g, "\\|")
|
|
499
|
+
.replace(/\r?\n/g, " ");
|
|
500
|
+
}
|
|
501
|
+
function cellText(value) {
|
|
502
|
+
return String(value ?? "");
|
|
503
|
+
}
|
|
504
|
+
function formatSheetRows(sheet, formatStyle) {
|
|
505
|
+
const previewRows = sheet.rows.slice(0, PROMPT_PREVIEW_ROWS);
|
|
506
|
+
if (previewRows.length === 0) {
|
|
507
|
+
return "";
|
|
508
|
+
}
|
|
509
|
+
switch (formatStyle) {
|
|
510
|
+
case "markdown": {
|
|
511
|
+
// `rows[0]` IS the header row (that is where `headers` came from), so
|
|
512
|
+
// the body always starts at index 1 — emitting row 0 again would
|
|
513
|
+
// duplicate the header underneath the separator.
|
|
514
|
+
const header = sheet.headers.length > 0 ? sheet.headers : previewRows[0].map(cellText);
|
|
515
|
+
const body = previewRows.slice(1);
|
|
516
|
+
const columnCount = Math.max(header.length, ...body.map((row) => row.length), 1);
|
|
517
|
+
const pad = (cells) => Array.from({ length: columnCount }, (_, i) => markdownEscape(cells[i] ?? ""));
|
|
518
|
+
return [
|
|
519
|
+
`| ${pad(header).join(" | ")} |`,
|
|
520
|
+
`| ${Array.from({ length: columnCount }, () => "---").join(" | ")} |`,
|
|
521
|
+
...body.map((row) => `| ${pad(row.map(cellText)).join(" | ")} |`),
|
|
522
|
+
].join("\n");
|
|
523
|
+
}
|
|
524
|
+
case "csv":
|
|
525
|
+
return previewRows
|
|
526
|
+
.map((row) => row.map((cell) => csvEscape(cellText(cell))).join(","))
|
|
527
|
+
.join("\n");
|
|
528
|
+
case "json": {
|
|
529
|
+
const rawHeader = sheet.headers.length > 0 ? sheet.headers : previewRows[0].map(cellText);
|
|
530
|
+
const body = previewRows.slice(1);
|
|
531
|
+
// A data row's own populated-cell count can exceed the header's — row
|
|
532
|
+
// extraction sizes each row on its own last populated cell, not a
|
|
533
|
+
// workbook-wide column count, so a header truncated by a merged cell
|
|
534
|
+
// (or a value landing in a column the header left blank) is a normal
|
|
535
|
+
// spreadsheet shape. "markdown" already sizes on the widest row for
|
|
536
|
+
// exactly this reason; do the same here instead of zipping strictly to
|
|
537
|
+
// header.length, which silently dropped every cell past it.
|
|
538
|
+
const columnCount = Math.max(rawHeader.length, ...body.map((row) => row.length), 1);
|
|
539
|
+
const extendedHeader = Array.from({ length: columnCount }, (_, i) => rawHeader[i] ?? `Column ${i + 1}`);
|
|
540
|
+
// Object.fromEntries silently drops a column when two header cells are
|
|
541
|
+
// literally the same string (a copy-pasted header, a merged-and-split
|
|
542
|
+
// sheet) — the later column's value overwrites the earlier one under
|
|
543
|
+
// the shared key. Dedupe first so every column keeps its own key.
|
|
544
|
+
const header = dedupeColumnNames(extendedHeader);
|
|
545
|
+
const objects = body.map((row) => Object.fromEntries(header.map((key, i) => [key, row[i] ?? null])));
|
|
546
|
+
return JSON.stringify(objects, null, 2);
|
|
547
|
+
}
|
|
548
|
+
case "raw":
|
|
549
|
+
default:
|
|
550
|
+
// Bug-for-bug with the pre-option behaviour: the header line is printed
|
|
551
|
+
// and then `rows` is printed in full, so row 1 appears twice. Callers
|
|
552
|
+
// that want a clean table ask for "markdown" or "csv".
|
|
553
|
+
return [
|
|
554
|
+
sheet.headers.join("\t"),
|
|
555
|
+
...previewRows.map((row) => row.map(cellText).join("\t")),
|
|
556
|
+
].join("\n");
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
/**
|
|
560
|
+
* Render processed worksheets into the text handed to the model.
|
|
561
|
+
*
|
|
562
|
+
* @param worksheets - Worksheets extracted from the workbook
|
|
563
|
+
* @param totalRows - Total row count across all extracted worksheets
|
|
564
|
+
* @param options - Office options; `sheetName` selects a single sheet and
|
|
565
|
+
* `formatStyle` chooses the rendering (default `raw`, the tab-separated
|
|
566
|
+
* preview that predates the option)
|
|
567
|
+
* @returns Prompt-ready text, or a message naming the available sheets when
|
|
568
|
+
* `sheetName` matches none of them
|
|
569
|
+
*/
|
|
570
|
+
export function formatWorksheetsForPrompt(worksheets, totalRows, options) {
|
|
571
|
+
const requested = options?.sheetName;
|
|
572
|
+
let selected = worksheets;
|
|
573
|
+
if (requested !== undefined) {
|
|
574
|
+
selected = worksheets.filter((sheet) => sheet.name === requested);
|
|
575
|
+
if (selected.length === 0) {
|
|
576
|
+
const available = worksheets.map((sheet) => sheet.name).join(", ");
|
|
577
|
+
return `Sheet "${requested}" not found. Available sheets: ${available || "(none)"}`;
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
const formatStyle = options?.formatStyle ?? "raw";
|
|
581
|
+
const selectedRows = selected.reduce((sum, sheet) => sum + sheet.rowCount, 0);
|
|
582
|
+
const scope = requested !== undefined
|
|
583
|
+
? `Spreadsheet: sheet "${requested}" of ${worksheets.length}, ${selectedRows} rows`
|
|
584
|
+
: `Spreadsheet: ${worksheets.length} sheet(s), ${totalRows} total rows`;
|
|
585
|
+
let text = `${scope}\n`;
|
|
586
|
+
for (const sheet of selected) {
|
|
587
|
+
text += `\n### Sheet: ${sheet.name}\n`;
|
|
588
|
+
text += `Columns (${sheet.columnCount}): ${sheet.headers.join(", ")}\n`;
|
|
589
|
+
text += `Rows: ${sheet.rowCount}\n`;
|
|
590
|
+
const rendered = formatSheetRows(sheet, formatStyle);
|
|
591
|
+
if (!rendered) {
|
|
592
|
+
continue;
|
|
593
|
+
}
|
|
594
|
+
text += `\nData:\n${rendered}\n`;
|
|
595
|
+
const remaining = sheet.rowCount - PROMPT_PREVIEW_ROWS;
|
|
596
|
+
if (remaining > 0) {
|
|
597
|
+
text += `... (${remaining} more rows)\n`;
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
return text;
|
|
601
|
+
}
|
|
602
|
+
// =============================================================================
|
|
485
603
|
// SINGLETON INSTANCE
|
|
486
604
|
// =============================================================================
|
|
487
605
|
/**
|
|
@@ -35,6 +35,7 @@ import { BaseFileProcessor } from "../base/BaseFileProcessor.js";
|
|
|
35
35
|
import { SIZE_LIMITS } from "../config/index.js";
|
|
36
36
|
import { FileErrorCode } from "../errors/index.js";
|
|
37
37
|
import { tryImport } from "../../utils/tryImport.js";
|
|
38
|
+
import { htmlToMarkdown } from "../../utils/htmlToMarkdown.js";
|
|
38
39
|
let _mammoth = null;
|
|
39
40
|
async function loadMammoth() {
|
|
40
41
|
if (_mammoth) {
|
|
@@ -64,6 +65,22 @@ const SUPPORTED_WORD_EXTENSIONS = [".docx", ".doc"];
|
|
|
64
65
|
* Word documents can be larger due to embedded images and complex formatting
|
|
65
66
|
*/
|
|
66
67
|
const WORD_TIMEOUT_MS = 60000;
|
|
68
|
+
/**
|
|
69
|
+
* Derive the document metrics from the extracted plain text.
|
|
70
|
+
*
|
|
71
|
+
* Counted off `textContent` rather than the markdown so the numbers describe
|
|
72
|
+
* the document's prose, not the syntax added to represent it.
|
|
73
|
+
*/
|
|
74
|
+
function measureText(textContent) {
|
|
75
|
+
const trimmed = textContent.trim();
|
|
76
|
+
return {
|
|
77
|
+
wordCount: trimmed ? trimmed.split(/\s+/).length : 0,
|
|
78
|
+
paragraphCount: textContent
|
|
79
|
+
.split(/\n+/)
|
|
80
|
+
.filter((line) => line.trim().length > 0).length,
|
|
81
|
+
characterCount: textContent.length,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
67
84
|
// =============================================================================
|
|
68
85
|
// WORD PROCESSOR CLASS
|
|
69
86
|
// =============================================================================
|
|
@@ -144,7 +161,9 @@ export class WordProcessor extends BaseFileProcessor {
|
|
|
144
161
|
return {
|
|
145
162
|
textContent: "",
|
|
146
163
|
htmlContent: "",
|
|
164
|
+
markdownContent: "",
|
|
147
165
|
warnings: [],
|
|
166
|
+
...measureText(""),
|
|
148
167
|
buffer,
|
|
149
168
|
mimetype: fileInfo.mimetype ||
|
|
150
169
|
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
|
@@ -267,7 +286,9 @@ export class WordProcessor extends BaseFileProcessor {
|
|
|
267
286
|
filename: this.getFilename(fileInfo),
|
|
268
287
|
textContent,
|
|
269
288
|
htmlContent,
|
|
289
|
+
markdownContent: htmlToMarkdown(htmlContent),
|
|
270
290
|
warnings,
|
|
291
|
+
...measureText(textContent),
|
|
271
292
|
},
|
|
272
293
|
};
|
|
273
294
|
}
|
|
@@ -19,8 +19,8 @@ function record(value) {
|
|
|
19
19
|
* (plain, carrying a complete tool pair, repeated, or opening with a signed
|
|
20
20
|
* `thinking` block). A `role: "system"` message is not — the Messages API
|
|
21
21
|
* requires the initial system prompt in the top-level `system` parameter.
|
|
22
|
-
* Items with no role (Codex `
|
|
23
|
-
*
|
|
22
|
+
* Items with no role (Codex `*_call` / `*_call_output`) are not turns and are
|
|
23
|
+
* left alone.
|
|
24
24
|
*/
|
|
25
25
|
function isDirectiveTurn(item) {
|
|
26
26
|
return record(item) && item.role === "system";
|
|
@@ -28,13 +28,26 @@ function isDirectiveTurn(item) {
|
|
|
28
28
|
function blocksOf(item) {
|
|
29
29
|
return Array.isArray(item.content) ? item.content : [item];
|
|
30
30
|
}
|
|
31
|
-
/**
|
|
31
|
+
/**
|
|
32
|
+
* Tool-call ids this item opens.
|
|
33
|
+
*
|
|
34
|
+
* Matched on the `_call` suffix rather than an enumerated list of item types.
|
|
35
|
+
* The Responses API has several call families — `function_call`,
|
|
36
|
+
* `custom_tool_call`, `local_shell_call`, `computer_call` — and an unrecognised
|
|
37
|
+
* one is worse than useless here: it opens no id, so unit grouping cannot see
|
|
38
|
+
* the pair and truncation is free to cut between a call and its answer. A live
|
|
39
|
+
* Codex session failed exactly that way, upstream rejecting the request with
|
|
40
|
+
* "No tool call found for custom tool call output with call_id ...". Suffix
|
|
41
|
+
* matching keeps the next family from reintroducing it silently.
|
|
42
|
+
*/
|
|
32
43
|
function definedCallIds(item) {
|
|
33
44
|
if (!record(item)) {
|
|
34
45
|
return [];
|
|
35
46
|
}
|
|
36
47
|
const ids = [];
|
|
37
|
-
if (
|
|
48
|
+
if (typeof item.type === "string" &&
|
|
49
|
+
item.type.endsWith("_call") &&
|
|
50
|
+
typeof item.call_id === "string") {
|
|
38
51
|
ids.push(item.call_id);
|
|
39
52
|
}
|
|
40
53
|
for (const block of blocksOf(item)) {
|
|
@@ -46,13 +59,20 @@ function definedCallIds(item) {
|
|
|
46
59
|
}
|
|
47
60
|
return ids;
|
|
48
61
|
}
|
|
49
|
-
/**
|
|
62
|
+
/**
|
|
63
|
+
* Tool-call ids this item answers.
|
|
64
|
+
*
|
|
65
|
+
* Suffix-matched for the same reason `definedCallIds` is. `_call_output` is
|
|
66
|
+
* checked rather than `_call` because no output type ends in `_call`, so the
|
|
67
|
+
* two predicates stay disjoint without ordering between them.
|
|
68
|
+
*/
|
|
50
69
|
function referencedCallIds(item) {
|
|
51
70
|
if (!record(item)) {
|
|
52
71
|
return [];
|
|
53
72
|
}
|
|
54
73
|
const ids = [];
|
|
55
|
-
if (item.type === "
|
|
74
|
+
if (typeof item.type === "string" &&
|
|
75
|
+
item.type.endsWith("_call_output") &&
|
|
56
76
|
typeof item.call_id === "string") {
|
|
57
77
|
ids.push(item.call_id);
|
|
58
78
|
}
|
|
@@ -69,7 +89,8 @@ function referencedCallIds(item) {
|
|
|
69
89
|
* Group items so a tool call and every answer to it stay in one unit.
|
|
70
90
|
*
|
|
71
91
|
* A unit stays open while any call it opened is still unanswered, so removing
|
|
72
|
-
* whole units can never strand a `tool_result` or
|
|
92
|
+
* whole units can never strand a tool answer — an Anthropic `tool_result` or
|
|
93
|
+
* any Responses API `*_call_output`.
|
|
73
94
|
*/
|
|
74
95
|
function groupIntoUnits(items) {
|
|
75
96
|
const units = [];
|
package/dist/types/file.d.ts
CHANGED
|
@@ -611,6 +611,21 @@ export type OfficeProcessorOptions = {
|
|
|
611
611
|
processAllSheets?: boolean;
|
|
612
612
|
/** For presentations (pptx only): whether to include slide notes */
|
|
613
613
|
includeSlideNotes?: boolean;
|
|
614
|
+
/**
|
|
615
|
+
* For spreadsheets (xlsx only): restrict processing to the named sheet.
|
|
616
|
+
* When the workbook has no sheet by that name the result says so and lists
|
|
617
|
+
* the names it does have, rather than silently falling back to every sheet.
|
|
618
|
+
* Omit to process every sheet (the default).
|
|
619
|
+
*/
|
|
620
|
+
sheetName?: string;
|
|
621
|
+
/**
|
|
622
|
+
* For spreadsheets (xlsx only): how sheet data is rendered into the prompt.
|
|
623
|
+
* - `raw` (default): tab-separated preview — the long-standing behaviour
|
|
624
|
+
* - `csv`: comma-separated values with RFC 4180 quoting
|
|
625
|
+
* - `markdown`: a markdown table per sheet
|
|
626
|
+
* - `json`: an array of row objects keyed by the header row
|
|
627
|
+
*/
|
|
628
|
+
formatStyle?: "raw" | "markdown" | "json" | "csv";
|
|
614
629
|
};
|
|
615
630
|
/**
|
|
616
631
|
* File detector options
|
package/dist/types/generate.d.ts
CHANGED
|
@@ -18,7 +18,7 @@ import type { AvatarOptions, AvatarResult } from "./avatar.js";
|
|
|
18
18
|
import type { MusicOptions, MusicResult } from "./music.js";
|
|
19
19
|
import type { StandardRecord, ValidationSchema, ZodUnknownSchema } from "./aliases.js";
|
|
20
20
|
import type { NeurolinkCredentials } from "./providers.js";
|
|
21
|
-
import type { CSVProcessorOptions, VideoProcessorOptions, FileWithMetadata, MultimodalAudioEntry, MultimodalVideoEntry, VisionImageOutputFormat } from "./file.js";
|
|
21
|
+
import type { CSVProcessorOptions, VideoProcessorOptions, OfficeProcessorOptions, FileWithMetadata, MultimodalAudioEntry, MultimodalVideoEntry, VisionImageOutputFormat } from "./file.js";
|
|
22
22
|
import type { WorkflowConfig } from "./workflow.js";
|
|
23
23
|
import type { Schema, Tool, ToolChoice } from "./tools.js";
|
|
24
24
|
import type { StepResult, LanguageModel } from "./providers.js";
|
|
@@ -150,6 +150,11 @@ export type GenerateOptions = {
|
|
|
150
150
|
music?: MusicOptions;
|
|
151
151
|
};
|
|
152
152
|
csvOptions?: CSVProcessorOptions;
|
|
153
|
+
/**
|
|
154
|
+
* Office document processing options. Currently consumed by the XLSX path
|
|
155
|
+
* (`sheetName`, `formatStyle`); see OfficeProcessorOptions.
|
|
156
|
+
*/
|
|
157
|
+
officeOptions?: OfficeProcessorOptions;
|
|
153
158
|
/** PDF processing options (#258). */
|
|
154
159
|
pdfOptions?: {
|
|
155
160
|
/** Password for an encrypted PDF (image-conversion fallback path). */
|
|
@@ -1437,6 +1442,11 @@ export type TextGenerationOptions = {
|
|
|
1437
1442
|
* saying so.
|
|
1438
1443
|
*/
|
|
1439
1444
|
videoOptions?: VideoProcessorOptions;
|
|
1445
|
+
/**
|
|
1446
|
+
* Office document processing options. Currently consumed by the XLSX path
|
|
1447
|
+
* (`sheetName`, `formatStyle`); see OfficeProcessorOptions.
|
|
1448
|
+
*/
|
|
1449
|
+
officeOptions?: OfficeProcessorOptions;
|
|
1440
1450
|
/** PDF processing options (#258). */
|
|
1441
1451
|
pdfOptions?: {
|
|
1442
1452
|
/** Password for an encrypted PDF (image-conversion fallback path). */
|
|
@@ -639,8 +639,19 @@ export type ProcessedWord = ProcessedFileBase & {
|
|
|
639
639
|
textContent: string;
|
|
640
640
|
/** HTML representation of the Word document */
|
|
641
641
|
htmlContent: string;
|
|
642
|
+
/**
|
|
643
|
+
* Markdown rendering of `htmlContent`, preserving the structure that plain
|
|
644
|
+
* text loses: headings, ordered/unordered lists and tables.
|
|
645
|
+
*/
|
|
646
|
+
markdownContent: string;
|
|
642
647
|
/** Warnings from mammoth extraction (e.g., unsupported elements) */
|
|
643
648
|
warnings: string[];
|
|
649
|
+
/** Whitespace-delimited word count of `textContent`. */
|
|
650
|
+
wordCount: number;
|
|
651
|
+
/** Count of non-empty text blocks in `textContent`. */
|
|
652
|
+
paragraphCount: number;
|
|
653
|
+
/** Character count of `textContent`, including whitespace. */
|
|
654
|
+
characterCount: number;
|
|
644
655
|
};
|
|
645
656
|
/**
|
|
646
657
|
* Processed RTF document result.
|
package/dist/types/stream.d.ts
CHANGED
|
@@ -16,7 +16,7 @@ import type { AIModelProviderConfig, NeurolinkCredentials } from "./providers.js
|
|
|
16
16
|
import type { TTSChunk, TTSOptions, TTSResult } from "./tts.js";
|
|
17
17
|
import type { STTOptions, STTResult } from "./stt.js";
|
|
18
18
|
import type { StandardRecord, ValidationSchema } from "./aliases.js";
|
|
19
|
-
import type { CSVProcessorOptions, FileWithMetadata, VideoProcessorOptions, VisionImageOutputFormat } from "./file.js";
|
|
19
|
+
import type { CSVProcessorOptions, FileWithMetadata, VideoProcessorOptions, VisionImageOutputFormat, OfficeProcessorOptions } from "./file.js";
|
|
20
20
|
import type { WorkflowConfig } from "./workflow.js";
|
|
21
21
|
import type { LanguageModel, StepResult } from "./providers.js";
|
|
22
22
|
import type { Tool, ToolChoice } from "./tools.js";
|
|
@@ -366,6 +366,11 @@ export type StreamOptions = {
|
|
|
366
366
|
* saying so.
|
|
367
367
|
*/
|
|
368
368
|
videoOptions?: VideoProcessorOptions;
|
|
369
|
+
/**
|
|
370
|
+
* Office document processing options. Currently consumed by the XLSX path
|
|
371
|
+
* (`sheetName`, `formatStyle`); see OfficeProcessorOptions.
|
|
372
|
+
*/
|
|
373
|
+
officeOptions?: OfficeProcessorOptions;
|
|
369
374
|
/** PDF processing options (#258). */
|
|
370
375
|
pdfOptions?: {
|
|
371
376
|
/** Password for an encrypted PDF (image-conversion fallback path). */
|
|
@@ -321,3 +321,22 @@ export type ScalarRecoveryDecision = {
|
|
|
321
321
|
} | {
|
|
322
322
|
kind: "not-json";
|
|
323
323
|
};
|
|
324
|
+
/**
|
|
325
|
+
* An element in the parsed HTML tree used for Markdown conversion.
|
|
326
|
+
*/
|
|
327
|
+
export type MarkdownHtmlElementNode = {
|
|
328
|
+
kind: "element";
|
|
329
|
+
/** Lower-cased tag name. */
|
|
330
|
+
tag: string;
|
|
331
|
+
/** Lower-cased attribute names mapped to their decoded values. */
|
|
332
|
+
attrs: Record<string, string>;
|
|
333
|
+
children: MarkdownHtmlNode[];
|
|
334
|
+
};
|
|
335
|
+
/**
|
|
336
|
+
* A node in the parsed HTML tree used for Markdown conversion: either a text
|
|
337
|
+
* run or an element.
|
|
338
|
+
*/
|
|
339
|
+
export type MarkdownHtmlNode = {
|
|
340
|
+
kind: "text";
|
|
341
|
+
value: string;
|
|
342
|
+
} | MarkdownHtmlElementNode;
|