flappa-doormal 2.19.0 → 2.21.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/AGENTS.md +63 -11
- package/README.md +383 -11
- package/dist/index.d.mts +440 -132
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +2 -4445
- package/dist/index.mjs.map +1 -1
- package/dist/mcp/server.d.mts +1 -0
- package/dist/mcp/server.mjs +156 -0
- package/dist/mcp/server.mjs.map +1 -0
- package/dist/segmentation-advisor-D375TL8-.mjs +6128 -0
- package/dist/segmentation-advisor-D375TL8-.mjs.map +1 -0
- package/package.json +18 -4
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { n as segmentPages, p as validateSegments, t as suggestSegmentationOptions } from "../segmentation-advisor-D375TL8-.mjs";
|
|
3
|
+
import { McpServer, StdioServerTransport } from "@modelcontextprotocol/server";
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
//#region src/mcp/tools.ts
|
|
6
|
+
const buildPreviewStats = (pages, options, segments, sampleSegments) => {
|
|
7
|
+
const validation = validateSegments(pages, options, segments);
|
|
8
|
+
const totalLength = segments.reduce((sum, segment) => sum + segment.content.length, 0);
|
|
9
|
+
const multiPageSegments = segments.filter((segment) => segment.to !== void 0 && segment.to !== segment.from).length;
|
|
10
|
+
return {
|
|
11
|
+
averageSegmentLength: segments.length === 0 ? 0 : totalLength / segments.length,
|
|
12
|
+
maxSegmentLength: Math.max(0, ...segments.map((segment) => segment.content.length)),
|
|
13
|
+
multiPageSegments,
|
|
14
|
+
segmentCount: segments.length,
|
|
15
|
+
segmentSamples: segments.slice(0, sampleSegments),
|
|
16
|
+
segments,
|
|
17
|
+
validation
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
const computeCandidateScore = (preview) => {
|
|
21
|
+
const issuePenalty = preview.validation.summary.issues * 100;
|
|
22
|
+
const multiPagePenalty = preview.multiPageSegments * 5;
|
|
23
|
+
const oversizePenalty = Math.floor(preview.maxSegmentLength / 500);
|
|
24
|
+
return Math.min(preview.segmentCount, 200) - issuePenalty - multiPagePenalty - oversizePenalty;
|
|
25
|
+
};
|
|
26
|
+
const inspectBook = (pages, options = {}) => {
|
|
27
|
+
const report = suggestSegmentationOptions(pages, options);
|
|
28
|
+
return {
|
|
29
|
+
assessment: report.assessment,
|
|
30
|
+
breakpointSuggestions: report.breakpointSuggestions,
|
|
31
|
+
lineStarts: report.lineStarts,
|
|
32
|
+
preprocess: report.preprocess,
|
|
33
|
+
repeatingSequences: report.repeatingSequences,
|
|
34
|
+
ruleSuggestions: report.ruleSuggestions
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
const suggestBookSegmentation = (pages, options = {}) => suggestSegmentationOptions(pages, options);
|
|
38
|
+
const previewSegmentation = (pages, options, sampleSegments = 10) => {
|
|
39
|
+
return buildPreviewStats(pages, options, segmentPages(pages, options), sampleSegments);
|
|
40
|
+
};
|
|
41
|
+
const validateSegmentationPreview = (pages, options, segments) => validateSegments(pages, options, segments);
|
|
42
|
+
const scoreSegmentationCandidates = (pages, candidates, sampleSegments = 5) => {
|
|
43
|
+
const results = candidates.map((options, index) => {
|
|
44
|
+
try {
|
|
45
|
+
const preview = previewSegmentation(pages, options, sampleSegments);
|
|
46
|
+
return {
|
|
47
|
+
averageSegmentLength: preview.averageSegmentLength,
|
|
48
|
+
index,
|
|
49
|
+
maxSegmentLength: preview.maxSegmentLength,
|
|
50
|
+
multiPageSegments: preview.multiPageSegments,
|
|
51
|
+
options,
|
|
52
|
+
score: computeCandidateScore(preview),
|
|
53
|
+
segmentCount: preview.segmentCount,
|
|
54
|
+
validation: preview.validation
|
|
55
|
+
};
|
|
56
|
+
} catch (error) {
|
|
57
|
+
return {
|
|
58
|
+
error: error instanceof Error ? error.message : String(error),
|
|
59
|
+
index,
|
|
60
|
+
options,
|
|
61
|
+
score: Number.NEGATIVE_INFINITY
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
return {
|
|
66
|
+
bestIndex: results.reduce((currentBest, result) => result.score > currentBest.score ? result : currentBest, results[0] ?? {
|
|
67
|
+
index: -1,
|
|
68
|
+
options: {},
|
|
69
|
+
score: Number.NEGATIVE_INFINITY
|
|
70
|
+
}).index,
|
|
71
|
+
results
|
|
72
|
+
};
|
|
73
|
+
};
|
|
74
|
+
//#endregion
|
|
75
|
+
//#region src/mcp/server.ts
|
|
76
|
+
const pageSchema = z.object({
|
|
77
|
+
content: z.string(),
|
|
78
|
+
id: z.number()
|
|
79
|
+
});
|
|
80
|
+
const segmentSchema = z.object({
|
|
81
|
+
content: z.string(),
|
|
82
|
+
from: z.number(),
|
|
83
|
+
meta: z.record(z.string(), z.unknown()).optional(),
|
|
84
|
+
to: z.number().optional()
|
|
85
|
+
});
|
|
86
|
+
const looseObjectSchema = z.object({}).catchall(z.unknown());
|
|
87
|
+
const pagesSchema = z.array(pageSchema);
|
|
88
|
+
const optionsSchema = looseObjectSchema;
|
|
89
|
+
const candidatesSchema = z.array(looseObjectSchema);
|
|
90
|
+
const outputSchema = looseObjectSchema;
|
|
91
|
+
const jsonResult = (payload) => ({
|
|
92
|
+
content: [{
|
|
93
|
+
text: JSON.stringify(payload, null, 2),
|
|
94
|
+
type: "text"
|
|
95
|
+
}],
|
|
96
|
+
structuredContent: payload
|
|
97
|
+
});
|
|
98
|
+
const server = new McpServer({
|
|
99
|
+
name: "flappa-doormal-mcp",
|
|
100
|
+
version: "2.20.0"
|
|
101
|
+
});
|
|
102
|
+
server.registerTool("inspect_book", {
|
|
103
|
+
description: "Inspect a book of Arabic pages and return analysis hints: preprocess detections, line-start patterns, repeating sequences, and draft rule suggestions.",
|
|
104
|
+
inputSchema: z.object({
|
|
105
|
+
advisorOptions: looseObjectSchema.optional(),
|
|
106
|
+
pages: pagesSchema
|
|
107
|
+
}),
|
|
108
|
+
outputSchema
|
|
109
|
+
}, async ({ advisorOptions, pages }) => jsonResult({ report: inspectBook(pages, advisorOptions) }));
|
|
110
|
+
server.registerTool("suggest_segmentation_options", {
|
|
111
|
+
description: "Generate a draft segmentation report and recommended SegmentationOptions for a book of Arabic pages.",
|
|
112
|
+
inputSchema: z.object({
|
|
113
|
+
advisorOptions: looseObjectSchema.optional(),
|
|
114
|
+
pages: pagesSchema
|
|
115
|
+
}),
|
|
116
|
+
outputSchema
|
|
117
|
+
}, async ({ advisorOptions, pages }) => jsonResult({ report: suggestBookSegmentation(pages, advisorOptions) }));
|
|
118
|
+
server.registerTool("preview_segmentation", {
|
|
119
|
+
description: "Run segmentPages on a book with caller-supplied SegmentationOptions and return segments, samples, and validation.",
|
|
120
|
+
inputSchema: z.object({
|
|
121
|
+
options: optionsSchema,
|
|
122
|
+
pages: pagesSchema,
|
|
123
|
+
sampleSegments: z.number().int().min(1).max(100).optional()
|
|
124
|
+
}),
|
|
125
|
+
outputSchema
|
|
126
|
+
}, async ({ options, pages, sampleSegments }) => jsonResult({ preview: previewSegmentation(pages, options, sampleSegments) }));
|
|
127
|
+
server.registerTool("validate_segmentation", {
|
|
128
|
+
description: "Validate a caller-provided segmentation result against source pages and the SegmentationOptions used to produce it.",
|
|
129
|
+
inputSchema: z.object({
|
|
130
|
+
options: optionsSchema,
|
|
131
|
+
pages: pagesSchema,
|
|
132
|
+
segments: z.array(segmentSchema)
|
|
133
|
+
}),
|
|
134
|
+
outputSchema
|
|
135
|
+
}, async ({ options, pages, segments }) => jsonResult({ validation: validateSegmentationPreview(pages, options, segments) }));
|
|
136
|
+
server.registerTool("score_candidate_options", {
|
|
137
|
+
description: "Evaluate multiple SegmentationOptions candidates against the same book and rank them using validation and segment-shape heuristics.",
|
|
138
|
+
inputSchema: z.object({
|
|
139
|
+
candidates: candidatesSchema,
|
|
140
|
+
pages: pagesSchema,
|
|
141
|
+
sampleSegments: z.number().int().min(1).max(100).optional()
|
|
142
|
+
}),
|
|
143
|
+
outputSchema
|
|
144
|
+
}, async ({ candidates, pages, sampleSegments }) => jsonResult({ ranking: scoreSegmentationCandidates(pages, candidates, sampleSegments) }));
|
|
145
|
+
const main = async () => {
|
|
146
|
+
const transport = new StdioServerTransport();
|
|
147
|
+
await server.connect(transport);
|
|
148
|
+
};
|
|
149
|
+
main().catch((error) => {
|
|
150
|
+
console.error(error instanceof Error ? error.stack ?? error.message : String(error));
|
|
151
|
+
process.exit(1);
|
|
152
|
+
});
|
|
153
|
+
//#endregion
|
|
154
|
+
export {};
|
|
155
|
+
|
|
156
|
+
//# sourceMappingURL=server.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.mjs","names":[],"sources":["../../src/mcp/tools.ts","../../src/mcp/server.ts"],"sourcesContent":["import { type SegmentationAdvisorOptions, suggestSegmentationOptions } from '@/analysis/segmentation-advisor.js';\nimport { segmentPages } from '@/segmentation/segmenter.js';\nimport type { Page, Segment } from '@/types/index.js';\nimport type { SegmentationOptions } from '@/types/options.js';\nimport type { SegmentValidationReport } from '@/types/validation.js';\nimport { validateSegments } from '@/validation/validate-segments.js';\n\nexport type SegmentationPreview = {\n averageSegmentLength: number;\n maxSegmentLength: number;\n multiPageSegments: number;\n segmentCount: number;\n segmentSamples: Segment[];\n segments: Segment[];\n validation: SegmentValidationReport;\n};\n\nexport type CandidateScore = {\n averageSegmentLength?: number;\n error?: string;\n index: number;\n maxSegmentLength?: number;\n multiPageSegments?: number;\n options: SegmentationOptions;\n score: number;\n segmentCount?: number;\n validation?: SegmentValidationReport;\n};\n\nconst buildPreviewStats = (\n pages: Page[],\n options: SegmentationOptions,\n segments: Segment[],\n sampleSegments: number,\n): SegmentationPreview => {\n const validation = validateSegments(pages, options, segments);\n const totalLength = segments.reduce((sum, segment) => sum + segment.content.length, 0);\n const multiPageSegments = segments.filter(\n (segment) => segment.to !== undefined && segment.to !== segment.from,\n ).length;\n\n return {\n averageSegmentLength: segments.length === 0 ? 0 : totalLength / segments.length,\n maxSegmentLength: Math.max(0, ...segments.map((segment) => segment.content.length)),\n multiPageSegments,\n segmentCount: segments.length,\n segmentSamples: segments.slice(0, sampleSegments),\n segments,\n validation,\n };\n};\n\nconst computeCandidateScore = (preview: SegmentationPreview): number => {\n const issuePenalty = preview.validation.summary.issues * 100;\n const multiPagePenalty = preview.multiPageSegments * 5;\n const oversizePenalty = Math.floor(preview.maxSegmentLength / 500);\n const segmentReward = Math.min(preview.segmentCount, 200);\n\n return segmentReward - issuePenalty - multiPagePenalty - oversizePenalty;\n};\n\nexport const inspectBook = (pages: Page[], options: SegmentationAdvisorOptions = {}) => {\n const report = suggestSegmentationOptions(pages, options);\n return {\n assessment: report.assessment,\n breakpointSuggestions: report.breakpointSuggestions,\n lineStarts: report.lineStarts,\n preprocess: report.preprocess,\n repeatingSequences: report.repeatingSequences,\n ruleSuggestions: report.ruleSuggestions,\n };\n};\n\nexport const suggestBookSegmentation = (pages: Page[], options: SegmentationAdvisorOptions = {}) =>\n suggestSegmentationOptions(pages, options);\n\nexport const previewSegmentation = (\n pages: Page[],\n options: SegmentationOptions,\n sampleSegments = 10,\n): SegmentationPreview => {\n const segments = segmentPages(pages, options);\n return buildPreviewStats(pages, options, segments, sampleSegments);\n};\n\nexport const validateSegmentationPreview = (\n pages: Page[],\n options: SegmentationOptions,\n segments: Segment[],\n): SegmentValidationReport => validateSegments(pages, options, segments);\n\nexport const scoreSegmentationCandidates = (\n pages: Page[],\n candidates: SegmentationOptions[],\n sampleSegments = 5,\n): {\n bestIndex: number;\n results: CandidateScore[];\n} => {\n const results = candidates.map<CandidateScore>((options, index) => {\n try {\n const preview = previewSegmentation(pages, options, sampleSegments);\n return {\n averageSegmentLength: preview.averageSegmentLength,\n index,\n maxSegmentLength: preview.maxSegmentLength,\n multiPageSegments: preview.multiPageSegments,\n options,\n score: computeCandidateScore(preview),\n segmentCount: preview.segmentCount,\n validation: preview.validation,\n };\n } catch (error) {\n return {\n error: error instanceof Error ? error.message : String(error),\n index,\n options,\n score: Number.NEGATIVE_INFINITY,\n };\n }\n });\n\n const best = results.reduce(\n (currentBest, result) => (result.score > currentBest.score ? result : currentBest),\n results[0] ?? { index: -1, options: {}, score: Number.NEGATIVE_INFINITY },\n );\n\n return {\n bestIndex: best.index,\n results,\n };\n};\n","#!/usr/bin/env node\n\nimport { McpServer, StdioServerTransport } from '@modelcontextprotocol/server';\nimport { z } from 'zod';\nimport {\n inspectBook,\n previewSegmentation,\n scoreSegmentationCandidates,\n suggestBookSegmentation,\n validateSegmentationPreview,\n} from './tools.js';\n\nconst pageSchema = z.object({\n content: z.string(),\n id: z.number(),\n});\n\nconst segmentSchema = z.object({\n content: z.string(),\n from: z.number(),\n meta: z.record(z.string(), z.unknown()).optional(),\n to: z.number().optional(),\n});\n\nconst looseObjectSchema = z.object({}).catchall(z.unknown());\nconst pagesSchema = z.array(pageSchema);\nconst optionsSchema = looseObjectSchema;\nconst candidatesSchema = z.array(looseObjectSchema);\nconst outputSchema = looseObjectSchema;\n\nconst jsonResult = (payload: Record<string, unknown>) => ({\n content: [{ text: JSON.stringify(payload, null, 2), type: 'text' as const }],\n structuredContent: payload,\n});\n\nconst server = new McpServer({\n name: 'flappa-doormal-mcp',\n version: '2.20.0',\n});\n\nserver.registerTool(\n 'inspect_book',\n {\n description:\n 'Inspect a book of Arabic pages and return analysis hints: preprocess detections, line-start patterns, repeating sequences, and draft rule suggestions.',\n inputSchema: z.object({\n advisorOptions: looseObjectSchema.optional(),\n pages: pagesSchema,\n }),\n outputSchema,\n },\n async ({ advisorOptions, pages }) =>\n jsonResult({\n report: inspectBook(pages, advisorOptions),\n }),\n);\n\nserver.registerTool(\n 'suggest_segmentation_options',\n {\n description:\n 'Generate a draft segmentation report and recommended SegmentationOptions for a book of Arabic pages.',\n inputSchema: z.object({\n advisorOptions: looseObjectSchema.optional(),\n pages: pagesSchema,\n }),\n outputSchema,\n },\n async ({ advisorOptions, pages }) =>\n jsonResult({\n report: suggestBookSegmentation(pages, advisorOptions),\n }),\n);\n\nserver.registerTool(\n 'preview_segmentation',\n {\n description:\n 'Run segmentPages on a book with caller-supplied SegmentationOptions and return segments, samples, and validation.',\n inputSchema: z.object({\n options: optionsSchema,\n pages: pagesSchema,\n sampleSegments: z.number().int().min(1).max(100).optional(),\n }),\n outputSchema,\n },\n async ({ options, pages, sampleSegments }) =>\n jsonResult({\n preview: previewSegmentation(pages, options, sampleSegments),\n }),\n);\n\nserver.registerTool(\n 'validate_segmentation',\n {\n description:\n 'Validate a caller-provided segmentation result against source pages and the SegmentationOptions used to produce it.',\n inputSchema: z.object({\n options: optionsSchema,\n pages: pagesSchema,\n segments: z.array(segmentSchema),\n }),\n outputSchema,\n },\n async ({ options, pages, segments }) =>\n jsonResult({\n validation: validateSegmentationPreview(pages, options, segments),\n }),\n);\n\nserver.registerTool(\n 'score_candidate_options',\n {\n description:\n 'Evaluate multiple SegmentationOptions candidates against the same book and rank them using validation and segment-shape heuristics.',\n inputSchema: z.object({\n candidates: candidatesSchema,\n pages: pagesSchema,\n sampleSegments: z.number().int().min(1).max(100).optional(),\n }),\n outputSchema,\n },\n async ({ candidates, pages, sampleSegments }) =>\n jsonResult({\n ranking: scoreSegmentationCandidates(pages, candidates, sampleSegments),\n }),\n);\n\nconst main = async () => {\n const transport = new StdioServerTransport();\n await server.connect(transport);\n};\n\nmain().catch((error) => {\n console.error(error instanceof Error ? (error.stack ?? error.message) : String(error));\n process.exit(1);\n});\n"],"mappings":"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"}
|