@tiwater/office-mcp 0.21.0 → 0.21.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.
|
@@ -16,7 +16,7 @@ export function resultChannels(args) {
|
|
|
16
16
|
return { returnContent, output };
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
export async function deliverLargeJsonResult({ tool, args, runtime, payload, sourcePaths }) {
|
|
19
|
+
export async function deliverLargeJsonResult({ tool, args, runtime, payload, sourcePaths, summary }) {
|
|
20
20
|
const channels = resultChannels(args);
|
|
21
21
|
const contentBytes = Buffer.byteLength(JSON.stringify(payload), 'utf8');
|
|
22
22
|
const contentReturned = channels.returnContent && contentBytes <= returnedContentBudgetBytes;
|
|
@@ -37,6 +37,7 @@ export async function deliverLargeJsonResult({ tool, args, runtime, payload, sou
|
|
|
37
37
|
contentReturned,
|
|
38
38
|
contentWritten: channels.output !== null,
|
|
39
39
|
},
|
|
40
|
+
...(summary === undefined ? {} : { summary }),
|
|
40
41
|
...(contentReturned ? { content: payload } : {}),
|
|
41
42
|
};
|
|
42
43
|
}
|
package/office/index.mjs
CHANGED
|
@@ -179,6 +179,39 @@ function largeResultOutput(tool) {
|
|
|
179
179
|
}).strict();
|
|
180
180
|
}
|
|
181
181
|
|
|
182
|
+
function largeInspectionOutput(tool, summary) {
|
|
183
|
+
return largeResultOutput(tool).extend({ summary }).strict();
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
const xlsxInspectionSummary = z.object({
|
|
187
|
+
sheetCount: z.number().int().nonnegative(),
|
|
188
|
+
sheets: z.array(z.object({
|
|
189
|
+
name: z.string(),
|
|
190
|
+
rowCount: z.number().int().nonnegative(),
|
|
191
|
+
columnCount: z.number().int().nonnegative(),
|
|
192
|
+
usedRange: z.string().nullable(),
|
|
193
|
+
mergedRangeCount: z.number().int().nonnegative(),
|
|
194
|
+
formulaCellCount: z.number().int().nonnegative(),
|
|
195
|
+
openingText: z.array(z.object({
|
|
196
|
+
reference: z.string(),
|
|
197
|
+
textPreview: z.string(),
|
|
198
|
+
}).strict()).max(6),
|
|
199
|
+
}).strict()).max(6),
|
|
200
|
+
}).strict();
|
|
201
|
+
|
|
202
|
+
const pptxInspectionSummary = z.object({
|
|
203
|
+
slideCount: z.number().int().nonnegative(),
|
|
204
|
+
masterCount: z.number().int().nonnegative(),
|
|
205
|
+
slideSize: z.object({
|
|
206
|
+
cx: z.number().int().nonnegative(),
|
|
207
|
+
cy: z.number().int().nonnegative(),
|
|
208
|
+
}).strict().nullable(),
|
|
209
|
+
openingSlides: z.array(z.object({
|
|
210
|
+
slideNumber: z.number().int().positive(),
|
|
211
|
+
textPreview: z.string(),
|
|
212
|
+
}).strict()).max(6),
|
|
213
|
+
}).strict();
|
|
214
|
+
|
|
182
215
|
function docxObservationOutput(tool) {
|
|
183
216
|
return z.object({
|
|
184
217
|
tool: z.literal(tool),
|
|
@@ -519,7 +552,7 @@ const tools = [
|
|
|
519
552
|
name: 'xlsx_inspect',
|
|
520
553
|
description: 'Inspect a current XLSX workbook or legacy XLS workbook, including workbook structure, exported values, formulas, styles, merged ranges, and published legacy-format conversion evidence. Set returnContent true to return the complete result when it fits the response limit. Provide output to write the complete result to a new JSON file. The two choices are independent and may be used together; at least one is required.',
|
|
521
554
|
inputSchema: inputContract('xlsx_inspect'),
|
|
522
|
-
outputSchema:
|
|
555
|
+
outputSchema: largeInspectionOutput('xlsx_inspect', xlsxInspectionSummary),
|
|
523
556
|
annotations: { readOnlyHint: true, idempotentHint: true },
|
|
524
557
|
handler: xlsxInspect,
|
|
525
558
|
},
|
|
@@ -544,7 +577,7 @@ const tools = [
|
|
|
544
577
|
name: 'pptx_inspect',
|
|
545
578
|
description: 'Inspect a PPTX file, including slides, masters, layouts, shapes, transforms, paragraphs, runs, and placeholders. Set returnContent true to return the complete result when it fits the response limit. Provide output to write the complete result to a new JSON file. The two choices are independent and may be used together; at least one is required.',
|
|
546
579
|
inputSchema: inputContract('pptx_inspect'),
|
|
547
|
-
outputSchema:
|
|
580
|
+
outputSchema: largeInspectionOutput('pptx_inspect', pptxInspectionSummary),
|
|
548
581
|
annotations: { readOnlyHint: true, idempotentHint: true },
|
|
549
582
|
handler: pptxInspect,
|
|
550
583
|
},
|
|
@@ -1146,7 +1179,14 @@ function nativeRenderBackend(sourceFormat) {
|
|
|
1146
1179
|
async function xlsxInspect(args) {
|
|
1147
1180
|
const input = path.resolve(requireString(args.input, 'input'));
|
|
1148
1181
|
const result = await runJsonCandidateChain(xlsxCandidates, ['inspect', input, '--json']);
|
|
1149
|
-
return deliverLargeJsonResult({
|
|
1182
|
+
return deliverLargeJsonResult({
|
|
1183
|
+
tool: 'xlsx_inspect',
|
|
1184
|
+
args,
|
|
1185
|
+
runtime: commandRuntime(result),
|
|
1186
|
+
payload: result.json,
|
|
1187
|
+
sourcePaths: [input],
|
|
1188
|
+
summary: compactXlsxInspection(result.json),
|
|
1189
|
+
});
|
|
1150
1190
|
}
|
|
1151
1191
|
|
|
1152
1192
|
async function xlsxExportJson(args) {
|
|
@@ -1168,7 +1208,14 @@ async function xlsxValidate(args) {
|
|
|
1168
1208
|
async function pptxInspect(args) {
|
|
1169
1209
|
const input = path.resolve(requireString(args.input, 'input'));
|
|
1170
1210
|
const result = await runJsonCandidateChain(pptxCandidates, ['inspect', input, '--json']);
|
|
1171
|
-
return deliverLargeJsonResult({
|
|
1211
|
+
return deliverLargeJsonResult({
|
|
1212
|
+
tool: 'pptx_inspect',
|
|
1213
|
+
args,
|
|
1214
|
+
runtime: commandRuntime(result),
|
|
1215
|
+
payload: result.json,
|
|
1216
|
+
sourcePaths: [input],
|
|
1217
|
+
summary: compactPptxInspection(result.json),
|
|
1218
|
+
});
|
|
1172
1219
|
}
|
|
1173
1220
|
|
|
1174
1221
|
async function pptxExportJson(args) {
|
|
@@ -1183,6 +1230,58 @@ async function pptxValidate(args) {
|
|
|
1183
1230
|
return deliverLargeJsonResult({ tool: 'pptx_validate', args, runtime: commandRuntime(result), payload: result.json, sourcePaths: [input] });
|
|
1184
1231
|
}
|
|
1185
1232
|
|
|
1233
|
+
function compactPreview(value, maximum) {
|
|
1234
|
+
return typeof value === 'string'
|
|
1235
|
+
? value.trim().replace(/\s+/gu, ' ').slice(0, maximum)
|
|
1236
|
+
: '';
|
|
1237
|
+
}
|
|
1238
|
+
|
|
1239
|
+
function compactXlsxInspection(payload) {
|
|
1240
|
+
const workbook = payload?.workbook ?? {};
|
|
1241
|
+
const allSheets = Array.isArray(workbook.sheets) ? workbook.sheets : [];
|
|
1242
|
+
return {
|
|
1243
|
+
sheetCount: Number.isInteger(workbook.sheetCount) ? workbook.sheetCount : allSheets.length,
|
|
1244
|
+
sheets: allSheets.slice(0, 6).map(sheet => ({
|
|
1245
|
+
name: compactPreview(sheet?.name, 120),
|
|
1246
|
+
rowCount: Number.isInteger(sheet?.rowCount) ? sheet.rowCount : 0,
|
|
1247
|
+
columnCount: Number.isInteger(sheet?.columnCount) ? sheet.columnCount : 0,
|
|
1248
|
+
usedRange: typeof sheet?.usedRange === 'string' ? compactPreview(sheet.usedRange, 120) : null,
|
|
1249
|
+
mergedRangeCount: Array.isArray(sheet?.mergedRanges) ? sheet.mergedRanges.length : 0,
|
|
1250
|
+
formulaCellCount: Number.isInteger(sheet?.formulaCellCount) ? sheet.formulaCellCount : 0,
|
|
1251
|
+
openingText: (Array.isArray(sheet?.textCells) ? sheet.textCells : [])
|
|
1252
|
+
.filter(cell => typeof cell?.text === 'string' && cell.text.trim() !== '')
|
|
1253
|
+
.slice(0, 6)
|
|
1254
|
+
.map(cell => ({
|
|
1255
|
+
reference: compactPreview(cell.reference, 40),
|
|
1256
|
+
textPreview: compactPreview(cell.text, 160),
|
|
1257
|
+
})),
|
|
1258
|
+
})),
|
|
1259
|
+
};
|
|
1260
|
+
}
|
|
1261
|
+
|
|
1262
|
+
function compactPptxInspection(payload) {
|
|
1263
|
+
const slides = Array.isArray(payload?.slides) ? payload.slides : [];
|
|
1264
|
+
return {
|
|
1265
|
+
slideCount: Number.isInteger(payload?.slideCount) ? payload.slideCount : slides.length,
|
|
1266
|
+
masterCount: Array.isArray(payload?.masters) ? payload.masters.length : 0,
|
|
1267
|
+
slideSize: Number.isInteger(payload?.slideSize?.cx) && Number.isInteger(payload?.slideSize?.cy)
|
|
1268
|
+
? { cx: payload.slideSize.cx, cy: payload.slideSize.cy }
|
|
1269
|
+
: null,
|
|
1270
|
+
openingSlides: slides.slice(0, 6).map((slide, index) => ({
|
|
1271
|
+
slideNumber: Number.isInteger(slide?.slideNumber) && slide.slideNumber > 0
|
|
1272
|
+
? slide.slideNumber
|
|
1273
|
+
: index + 1,
|
|
1274
|
+
textPreview: compactPreview(
|
|
1275
|
+
(Array.isArray(slide?.shapes) ? slide.shapes : [])
|
|
1276
|
+
.map(shape => shape?.text)
|
|
1277
|
+
.filter(text => typeof text === 'string' && text.trim() !== '')
|
|
1278
|
+
.join(' '),
|
|
1279
|
+
240,
|
|
1280
|
+
),
|
|
1281
|
+
})),
|
|
1282
|
+
};
|
|
1283
|
+
}
|
|
1284
|
+
|
|
1186
1285
|
async function requireReturnedArtifact(returned, expectedPath, label) {
|
|
1187
1286
|
if (!returned || path.resolve(returned.path || '') !== expectedPath) {
|
|
1188
1287
|
throw new Error(`${label} artifact is not bound to the accepted provider call`);
|