@spinabot/brigade 1.9.0 → 1.10.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.
Files changed (97) hide show
  1. package/README.md +12 -10
  2. package/dist/agents/agent-loop.d.ts +55 -0
  3. package/dist/agents/agent-loop.d.ts.map +1 -1
  4. package/dist/agents/agent-loop.js +90 -1
  5. package/dist/agents/agent-loop.js.map +1 -1
  6. package/dist/agents/channels/inbound-pipeline.d.ts +22 -0
  7. package/dist/agents/channels/inbound-pipeline.d.ts.map +1 -1
  8. package/dist/agents/channels/inbound-pipeline.js +31 -1
  9. package/dist/agents/channels/inbound-pipeline.js.map +1 -1
  10. package/dist/agents/channels/media-capture.d.ts +69 -6
  11. package/dist/agents/channels/media-capture.d.ts.map +1 -1
  12. package/dist/agents/channels/media-capture.js +125 -8
  13. package/dist/agents/channels/media-capture.js.map +1 -1
  14. package/dist/agents/channels/telegram/media.d.ts.map +1 -1
  15. package/dist/agents/channels/telegram/media.js +16 -4
  16. package/dist/agents/channels/telegram/media.js.map +1 -1
  17. package/dist/agents/channels/whatsapp/media.d.ts +19 -0
  18. package/dist/agents/channels/whatsapp/media.d.ts.map +1 -1
  19. package/dist/agents/channels/whatsapp/media.js +37 -2
  20. package/dist/agents/channels/whatsapp/media.js.map +1 -1
  21. package/dist/agents/media-understanding/anthropic-adapter.d.ts +49 -0
  22. package/dist/agents/media-understanding/anthropic-adapter.d.ts.map +1 -0
  23. package/dist/agents/media-understanding/anthropic-adapter.js +162 -0
  24. package/dist/agents/media-understanding/anthropic-adapter.js.map +1 -0
  25. package/dist/agents/media-understanding/config.d.ts +57 -0
  26. package/dist/agents/media-understanding/config.d.ts.map +1 -0
  27. package/dist/agents/media-understanding/config.js +289 -0
  28. package/dist/agents/media-understanding/config.js.map +1 -0
  29. package/dist/agents/media-understanding/gemini-adapter.d.ts +57 -0
  30. package/dist/agents/media-understanding/gemini-adapter.d.ts.map +1 -0
  31. package/dist/agents/media-understanding/gemini-adapter.js +343 -0
  32. package/dist/agents/media-understanding/gemini-adapter.js.map +1 -0
  33. package/dist/agents/media-understanding/index.d.ts +58 -0
  34. package/dist/agents/media-understanding/index.d.ts.map +1 -0
  35. package/dist/agents/media-understanding/index.js +275 -0
  36. package/dist/agents/media-understanding/index.js.map +1 -0
  37. package/dist/agents/media-understanding/pi-adapter.d.ts +72 -0
  38. package/dist/agents/media-understanding/pi-adapter.d.ts.map +1 -0
  39. package/dist/agents/media-understanding/pi-adapter.js +160 -0
  40. package/dist/agents/media-understanding/pi-adapter.js.map +1 -0
  41. package/dist/agents/media-understanding/types.d.ts +189 -0
  42. package/dist/agents/media-understanding/types.d.ts.map +1 -0
  43. package/dist/agents/media-understanding/types.js +51 -0
  44. package/dist/agents/media-understanding/types.js.map +1 -0
  45. package/dist/agents/session-wiring.d.ts +11 -0
  46. package/dist/agents/session-wiring.d.ts.map +1 -1
  47. package/dist/agents/session-wiring.js +1 -0
  48. package/dist/agents/session-wiring.js.map +1 -1
  49. package/dist/agents/tools/analyze-media-tool.d.ts +263 -0
  50. package/dist/agents/tools/analyze-media-tool.d.ts.map +1 -0
  51. package/dist/agents/tools/analyze-media-tool.js +2321 -0
  52. package/dist/agents/tools/analyze-media-tool.js.map +1 -0
  53. package/dist/agents/tools/doc-shared.d.ts +187 -0
  54. package/dist/agents/tools/doc-shared.d.ts.map +1 -0
  55. package/dist/agents/tools/doc-shared.js +484 -0
  56. package/dist/agents/tools/doc-shared.js.map +1 -0
  57. package/dist/agents/tools/edit-document-tool.d.ts +133 -0
  58. package/dist/agents/tools/edit-document-tool.d.ts.map +1 -0
  59. package/dist/agents/tools/edit-document-tool.js +815 -0
  60. package/dist/agents/tools/edit-document-tool.js.map +1 -0
  61. package/dist/agents/tools/image-downscale.d.ts +93 -0
  62. package/dist/agents/tools/image-downscale.d.ts.map +1 -0
  63. package/dist/agents/tools/image-downscale.js +257 -0
  64. package/dist/agents/tools/image-downscale.js.map +1 -0
  65. package/dist/agents/tools/make-document-tool.d.ts +114 -0
  66. package/dist/agents/tools/make-document-tool.d.ts.map +1 -0
  67. package/dist/agents/tools/make-document-tool.js +542 -0
  68. package/dist/agents/tools/make-document-tool.js.map +1 -0
  69. package/dist/agents/tools/media-cache.d.ts +56 -0
  70. package/dist/agents/tools/media-cache.d.ts.map +1 -0
  71. package/dist/agents/tools/media-cache.js +133 -0
  72. package/dist/agents/tools/media-cache.js.map +1 -0
  73. package/dist/agents/tools/ooxml-images.d.ts +107 -0
  74. package/dist/agents/tools/ooxml-images.d.ts.map +1 -0
  75. package/dist/agents/tools/ooxml-images.js +308 -0
  76. package/dist/agents/tools/ooxml-images.js.map +1 -0
  77. package/dist/agents/tools/registry.d.ts +12 -0
  78. package/dist/agents/tools/registry.d.ts.map +1 -1
  79. package/dist/agents/tools/registry.js +47 -0
  80. package/dist/agents/tools/registry.js.map +1 -1
  81. package/dist/buildstamp.json +1 -1
  82. package/dist/cli/commands/doctor.d.ts.map +1 -1
  83. package/dist/cli/commands/doctor.js +41 -0
  84. package/dist/cli/commands/doctor.js.map +1 -1
  85. package/dist/core/console-stream.d.ts.map +1 -1
  86. package/dist/core/console-stream.js +7 -5
  87. package/dist/core/console-stream.js.map +1 -1
  88. package/dist/core/server.js +6 -1
  89. package/dist/core/server.js.map +1 -1
  90. package/dist/system-prompt/assembler.d.ts.map +1 -1
  91. package/dist/system-prompt/assembler.js +25 -1
  92. package/dist/system-prompt/assembler.js.map +1 -1
  93. package/dist/system-prompt/guidance.d.ts +30 -0
  94. package/dist/system-prompt/guidance.d.ts.map +1 -1
  95. package/dist/system-prompt/guidance.js +50 -0
  96. package/dist/system-prompt/guidance.js.map +1 -1
  97. package/package.json +9 -1
@@ -0,0 +1,542 @@
1
+ /**
2
+ * `make_document` — CREATE a Word / Excel / PowerPoint / PDF file from
3
+ * structured content. The WRITE keystone of Brigade's "cowork assistant"
4
+ * surface; the create-side sibling of `analyze_media` (read) and the producer
5
+ * for `send_media` (deliver).
6
+ *
7
+ * ─────────────────────────────────────────────────────────────────────────
8
+ * WHY A NATIVE TOOL (read before changing)
9
+ * ─────────────────────────────────────────────────────────────────────────
10
+ * Brigade has NO code sandbox and is pure-JS by doctrine — there is no
11
+ * python / pandoc / libreoffice to shell out to. Hand-rolling a .docx in
12
+ * `bash` is impossible (OOXML is a zip of XML) and producing one any other way
13
+ * silently fails. So document creation is a first-class tool backed by pure-JS
14
+ * libraries with zero native build:
15
+ * - docx → `docx` (Document + Packer)
16
+ * - xlsx → `exceljs` (Workbook)
17
+ * - pptx → `pptxgenjs`
18
+ * - pdf → `@cantoo/pdf-lib` (maintained pdf-lib fork)
19
+ * Images embed via `jimp` (decode + fit + re-encode to a library-friendly
20
+ * raster) — see `doc-shared.ts`.
21
+ *
22
+ * SECURITY: the output path is resolved + scoped through the SAME guard as
23
+ * `analyze_media`'s local reads (`resolveOutputPath` → media-path denylist +
24
+ * allowed-root containment). Writing outside workspace / cwd / cache / temp is
25
+ * refused. Default output lands in the workspace. NOT owner-only — creating a
26
+ * file into the workspace is safe, and the path guard is the real boundary.
27
+ *
28
+ * DELIVERY: the tool writes the file + returns `{ok, path, format, bytes}`. The
29
+ * agent hands it to the user via `send_media({path})` on a channel (the doc MIME
30
+ * is already mapped there) or reports the workspace path on the TUI.
31
+ */
32
+ import { Type } from "typebox";
33
+ import { jsonResult } from "./common.js";
34
+ import { acquireImageForEmbed, defaultOutputName, embedUnicodeFont, isFormulaCell, resolveOutputPath, sanitizeForFont, toExcelCellValue, writeDocFile, } from "./doc-shared.js";
35
+ /* ─────────────────────────── params ─────────────────────────── */
36
+ /** An image reference embeddable in docx/pptx/pdf content. */
37
+ const ImageRef = Type.Object({
38
+ path: Type.Optional(Type.String({ description: "Local file path to the image (scoped to allowed roots)." })),
39
+ url: Type.Optional(Type.String({ description: "http(s) URL to the image (SSRF-guarded)." })),
40
+ });
41
+ /** A simple table (rows of string cells). */
42
+ const TableSpec = Type.Object({
43
+ rows: Type.Array(Type.Array(Type.String()), {
44
+ description: "Table rows; each row is an array of cell strings. The first row is treated as a header.",
45
+ }),
46
+ });
47
+ const DocxSection = Type.Object({
48
+ heading: Type.Optional(Type.String({ description: "Section heading text." })),
49
+ level: Type.Optional(Type.Integer({ minimum: 1, maximum: 6, description: "Heading level 1-6 (default 1)." })),
50
+ paragraphs: Type.Optional(Type.Array(Type.String(), { description: "Body paragraphs." })),
51
+ bullets: Type.Optional(Type.Array(Type.String(), { description: "Bulleted list items." })),
52
+ table: Type.Optional(TableSpec),
53
+ image: Type.Optional(ImageRef),
54
+ });
55
+ const PdfPage = Type.Object({
56
+ heading: Type.Optional(Type.String({ description: "Page heading." })),
57
+ paragraphs: Type.Optional(Type.Array(Type.String(), { description: "Body paragraphs (wrapped to the page width)." })),
58
+ image: Type.Optional(ImageRef),
59
+ });
60
+ /** A formula cell: `{ formula: "SUM(B2:B10)" }` (no leading "="). */
61
+ const FormulaCell = Type.Object({
62
+ formula: Type.String({ description: 'An Excel formula WITHOUT the leading "=" (e.g. "SUM(B2:B10)").' }),
63
+ numFmt: Type.Optional(Type.String({ description: 'Optional number format for this cell (e.g. "#,##0.00").' })),
64
+ });
65
+ /** A cell value: a string, a number, or a formula object. */
66
+ const XlsxCellValue = Type.Union([Type.String(), Type.Number(), FormulaCell]);
67
+ const XlsxSheet = Type.Object({
68
+ name: Type.Optional(Type.String({ description: "Sheet name (default Sheet1, Sheet2, …)." })),
69
+ header: Type.Optional(Type.Array(Type.String(), { description: "Optional header row (bolded)." })),
70
+ rows: Type.Array(Type.Array(XlsxCellValue), {
71
+ description: 'Data rows; each cell is a string, a number, or a formula object { formula: "SUM(A1:A3)", numFmt? }.',
72
+ }),
73
+ numberFormats: Type.Optional(Type.Array(Type.Union([Type.String(), Type.Null()]), {
74
+ description: 'Optional per-column number formats, by column index (e.g. ["@", "#,##0.00", "0%"]). null/"" leaves a column default.',
75
+ })),
76
+ });
77
+ /** A single named data series for a chart. */
78
+ const ChartSeries = Type.Object({
79
+ name: Type.Optional(Type.String({ description: "Series label (legend)." })),
80
+ values: Type.Array(Type.Number(), { description: "Numeric values, aligned to `categories`." }),
81
+ });
82
+ /** A chart placed on a slide (bar / line / pie). */
83
+ const ChartSpec = Type.Object({
84
+ type: Type.Union([Type.Literal("bar"), Type.Literal("line"), Type.Literal("pie")], {
85
+ description: "Chart type: bar, line, or pie.",
86
+ }),
87
+ title: Type.Optional(Type.String({ description: "Chart title." })),
88
+ categories: Type.Array(Type.String(), { description: "Category (x-axis) labels." }),
89
+ series: Type.Array(ChartSeries, { description: "One or more data series (pie uses the first)." }),
90
+ });
91
+ const PptxSlide = Type.Object({
92
+ title: Type.Optional(Type.String({ description: "Slide title." })),
93
+ bullets: Type.Optional(Type.Array(Type.String(), { description: "Slide bullet points." })),
94
+ image: Type.Optional(ImageRef),
95
+ chart: Type.Optional(ChartSpec),
96
+ notes: Type.Optional(Type.String({ description: "Speaker notes." })),
97
+ });
98
+ const DocContent = Type.Object({
99
+ title: Type.Optional(Type.String({ description: "Document title (docx/pdf cover heading)." })),
100
+ sections: Type.Optional(Type.Array(DocxSection, { description: "docx sections." })),
101
+ pages: Type.Optional(Type.Array(PdfPage, { description: "pdf pages." })),
102
+ sheets: Type.Optional(Type.Array(XlsxSheet, { description: "xlsx sheets." })),
103
+ slides: Type.Optional(Type.Array(PptxSlide, { description: "pptx slides." })),
104
+ });
105
+ const MakeDocumentParams = Type.Object({
106
+ format: Type.Union([Type.Literal("docx"), Type.Literal("xlsx"), Type.Literal("pptx"), Type.Literal("pdf")], {
107
+ description: "The document format to create: docx (Word), xlsx (Excel), pptx (PowerPoint), or pdf.",
108
+ }),
109
+ outputPath: Type.Optional(Type.String({
110
+ description: "Where to write the file. Relative paths resolve against the workspace; omit for an auto-named file in the workspace (e.g. document-ab12cd.docx). Must land inside an allowed root (workspace / cwd / cache / temp).",
111
+ })),
112
+ content: Type.Optional(Type.Intersect([DocContent], {
113
+ description: "Structured content keyed by format: docx→{title?, sections:[{heading?,level?,paragraphs?,bullets?,table?,image?}]}; xlsx→{sheets:[{name?,header?,rows}]}; pptx→{slides:[{title?,bullets?,image?,notes?}]}; pdf→{title?, pages:[{heading?,paragraphs?,image?}]}.",
114
+ })),
115
+ });
116
+ export function makeMakeDocumentTool(opts = {}) {
117
+ const rootOpts = {
118
+ ...(opts.workspaceDir ? { workspaceDir: opts.workspaceDir } : {}),
119
+ ...(opts.cwd ? { cwd: opts.cwd } : {}),
120
+ };
121
+ const imageOpts = {
122
+ ...rootOpts,
123
+ ...(opts.loadImage ? { loadImage: opts.loadImage } : {}),
124
+ };
125
+ return {
126
+ name: "make_document",
127
+ label: "Make Document",
128
+ displaySummary: "creating a document",
129
+ // NOT owner-only: creating a file into the workspace is a safe, read-like
130
+ // capability. The path guard (resolveOutputPath) is the real boundary and
131
+ // runs for every sender.
132
+ ownerOnly: false,
133
+ description: [
134
+ "Create a Word (docx), Excel (xlsx), PowerPoint (pptx), or PDF file from structured content, then return its path.",
135
+ "Pass `format` and `content` (shape depends on format): docx→{title?, sections:[{heading?,level?,paragraphs?,bullets?,table?,image?}]}; xlsx→{sheets:[{name?,header?,rows}]}; pptx→{slides:[{title?,bullets?,image?,notes?}]}; pdf→{title?, pages:[{heading?,paragraphs?,image?}]}.",
136
+ "Images embed from a local `path` or `url`. The file is written into the workspace by default (pass `outputPath` to choose). To send it to the user, follow up with `send_media({path})`; to change an existing file use `edit_document`. Never hand-roll a document in bash — this is the only correct surface.",
137
+ ].join(" "),
138
+ parameters: MakeDocumentParams,
139
+ execute: async (_toolCallId, args, signal) => {
140
+ const format = args.format;
141
+ const content = args.content ?? {};
142
+ const outRaw = typeof args.outputPath === "string" && args.outputPath.trim()
143
+ ? args.outputPath.trim()
144
+ : defaultOutputName(format);
145
+ // Resolve + scope the output path BEFORE building bytes (fail fast on a
146
+ // refused path so we don't waste the build).
147
+ const absPath = resolveOutputPath(outRaw, rootOpts);
148
+ let bytes;
149
+ let details;
150
+ switch (format) {
151
+ case "docx": {
152
+ const built = await buildDocx(content, imageOpts, signal);
153
+ bytes = built.bytes;
154
+ details = { ok: true, format, sections: built.sections };
155
+ break;
156
+ }
157
+ case "xlsx": {
158
+ const built = await buildXlsx(content);
159
+ bytes = built.bytes;
160
+ details = { ok: true, format, sheets: built.sheets };
161
+ break;
162
+ }
163
+ case "pptx": {
164
+ const built = await buildPptx(content, imageOpts, signal);
165
+ bytes = built.bytes;
166
+ details = { ok: true, format, slides: built.slides };
167
+ break;
168
+ }
169
+ case "pdf": {
170
+ const built = await buildPdf(content, imageOpts, signal);
171
+ bytes = built.bytes;
172
+ details = { ok: true, format, pages: built.pages };
173
+ break;
174
+ }
175
+ }
176
+ const written = await writeDocFile(absPath, bytes);
177
+ return jsonResult({ ...details, path: absPath, bytes: written });
178
+ },
179
+ };
180
+ }
181
+ /* ─────────────────────────── docx builder ─────────────────────────── */
182
+ async function buildDocx(content, imageOpts, signal) {
183
+ const docx = await import("docx");
184
+ const { Document, Packer, Paragraph, TextRun, HeadingLevel, Table, TableRow, TableCell, ImageRun, WidthType } = docx;
185
+ const headingFor = (level) => {
186
+ switch (level) {
187
+ case 1:
188
+ return HeadingLevel.HEADING_1;
189
+ case 2:
190
+ return HeadingLevel.HEADING_2;
191
+ case 3:
192
+ return HeadingLevel.HEADING_3;
193
+ case 4:
194
+ return HeadingLevel.HEADING_4;
195
+ case 5:
196
+ return HeadingLevel.HEADING_5;
197
+ case 6:
198
+ return HeadingLevel.HEADING_6;
199
+ default:
200
+ return HeadingLevel.HEADING_1;
201
+ }
202
+ };
203
+ const children = [];
204
+ const blocks = [];
205
+ if (content.title && content.title.trim()) {
206
+ blocks.push(new Paragraph({ text: content.title.trim(), heading: HeadingLevel.TITLE }));
207
+ }
208
+ const sections = Array.isArray(content.sections) ? content.sections : [];
209
+ for (const section of sections) {
210
+ if (section.heading && section.heading.trim()) {
211
+ blocks.push(new Paragraph({ text: section.heading.trim(), heading: headingFor(section.level) }));
212
+ }
213
+ for (const para of section.paragraphs ?? []) {
214
+ blocks.push(new Paragraph({ children: [new TextRun(String(para ?? ""))] }));
215
+ }
216
+ for (const bullet of section.bullets ?? []) {
217
+ blocks.push(new Paragraph({ text: String(bullet ?? ""), bullet: { level: 0 } }));
218
+ }
219
+ if (section.table && Array.isArray(section.table.rows) && section.table.rows.length > 0) {
220
+ const rows = section.table.rows.map((row, rowIdx) => new TableRow({
221
+ children: (row ?? []).map((cell) => new TableCell({
222
+ children: [
223
+ new Paragraph({
224
+ children: [new TextRun({ text: String(cell ?? ""), bold: rowIdx === 0 })],
225
+ }),
226
+ ],
227
+ })),
228
+ }));
229
+ blocks.push(new Table({ rows, width: { size: 100, type: WidthType.PERCENTAGE } }));
230
+ }
231
+ if (section.image && (section.image.path || section.image.url)) {
232
+ const img = await acquireImageForEmbed(section.image, { ...imageOpts, ...(signal ? { signal } : {}) });
233
+ const { width, height } = fitDimensions(img.width, img.height, 600, 600);
234
+ blocks.push(new Paragraph({
235
+ children: [
236
+ new ImageRun({
237
+ // docx's ImageRun uses "jpg" (not the MIME "jpeg") for its type tag.
238
+ type: img.format === "jpeg" ? "jpg" : "png",
239
+ data: img.bytes,
240
+ transformation: { width, height },
241
+ }),
242
+ ],
243
+ }));
244
+ }
245
+ }
246
+ // A wholly-empty doc still needs at least one paragraph to be valid.
247
+ if (blocks.length === 0)
248
+ blocks.push(new Paragraph({ children: [new TextRun("")] }));
249
+ void children;
250
+ const doc = new Document({ sections: [{ children: blocks }] });
251
+ const bytes = await Packer.toBuffer(doc);
252
+ return { bytes: Buffer.isBuffer(bytes) ? bytes : Buffer.from(bytes), sections: sections.length };
253
+ }
254
+ /* ─────────────────────────── xlsx builder ─────────────────────────── */
255
+ async function buildXlsx(content) {
256
+ const ExcelJSImport = await import("exceljs");
257
+ const ExcelJS = ExcelJSImport.default ?? ExcelJSImport;
258
+ const workbook = new ExcelJS.Workbook();
259
+ workbook.creator = "Brigade";
260
+ workbook.created = new Date();
261
+ const sheets = Array.isArray(content.sheets) ? content.sheets : [];
262
+ const effective = sheets.length > 0 ? sheets : [{ rows: [] }];
263
+ let idx = 0;
264
+ for (const sheet of effective) {
265
+ idx += 1;
266
+ const name = sanitizeSheetName(sheet.name, idx);
267
+ const ws = workbook.addWorksheet(name);
268
+ // Optional per-column number formats applied to data rows below.
269
+ const columnFormats = Array.isArray(sheet.numberFormats)
270
+ ? (sheet.numberFormats ?? [])
271
+ : [];
272
+ if (Array.isArray(sheet.header) && sheet.header.length > 0) {
273
+ const headerRow = ws.addRow(sheet.header.map((h) => String(h ?? "")));
274
+ headerRow.font = { bold: true };
275
+ }
276
+ const dataRows = (sheet.rows ?? []);
277
+ for (const row of dataRows) {
278
+ const added = ws.addRow([]);
279
+ (row ?? []).forEach((c, colIdx) => {
280
+ const cell = added.getCell(colIdx + 1);
281
+ cell.value = toExcelCellValue(c);
282
+ // Per-cell numFmt (formula objects may carry one) wins over the column.
283
+ const cellFmt = isFormulaCell(c) && typeof c.numFmt === "string" ? c.numFmt : undefined;
284
+ const colFmt = typeof columnFormats[colIdx] === "string" ? columnFormats[colIdx] : undefined;
285
+ const fmt = cellFmt || colFmt;
286
+ if (fmt)
287
+ cell.numFmt = fmt;
288
+ });
289
+ added.commit();
290
+ }
291
+ }
292
+ const out = await workbook.xlsx.writeBuffer();
293
+ return { bytes: Buffer.from(out), sheets: effective.length };
294
+ }
295
+ /** Excel sheet names: ≤31 chars, no []:*?/\ — fall back to SheetN. */
296
+ function sanitizeSheetName(name, idx) {
297
+ const cleaned = (name ?? "").replace(/[[\]:*?/\\]/g, " ").trim().slice(0, 31);
298
+ return cleaned.length > 0 ? cleaned : `Sheet${idx}`;
299
+ }
300
+ /* ─────────────────────────── pptx builder ─────────────────────────── */
301
+ async function buildPptx(content, imageOpts, signal) {
302
+ const PptxImport = await import("pptxgenjs");
303
+ const PptxGenJS = PptxImport.default ??
304
+ PptxImport;
305
+ const pres = new PptxGenJS();
306
+ const slides = Array.isArray(content.slides) ? content.slides : [];
307
+ const effective = slides.length > 0 ? slides : [{}];
308
+ for (const spec of effective) {
309
+ const slide = pres.addSlide();
310
+ if (spec.title && spec.title.trim()) {
311
+ slide.addText(spec.title.trim(), {
312
+ x: 0.5,
313
+ y: 0.3,
314
+ w: 9,
315
+ h: 1,
316
+ fontSize: 28,
317
+ bold: true,
318
+ });
319
+ }
320
+ const bullets = (spec.bullets ?? []).filter((b) => typeof b === "string");
321
+ if (bullets.length > 0) {
322
+ slide.addText(bullets.map((b) => ({ text: String(b ?? ""), options: { bullet: true } })), { x: 0.7, y: 1.5, w: spec.image ? 5.3 : 8.6, h: 4.5, fontSize: 18 });
323
+ }
324
+ if (spec.image && (spec.image.path || spec.image.url)) {
325
+ const img = await acquireImageForEmbed(spec.image, { ...imageOpts, ...(signal ? { signal } : {}) });
326
+ const { width, height } = fitDimensions(img.width, img.height, 360, 360);
327
+ slide.addImage({
328
+ data: `data:${img.mimeType};base64,${img.bytes.toString("base64")}`,
329
+ x: bullets.length > 0 ? 6.2 : 2.5,
330
+ y: 1.6,
331
+ w: width / 96,
332
+ h: height / 96,
333
+ });
334
+ }
335
+ if (spec.chart && typeof slide.addChart === "function") {
336
+ addSlideChart(slide, spec.chart);
337
+ }
338
+ if (spec.notes && spec.notes.trim() && typeof slide.addNotes === "function") {
339
+ slide.addNotes(spec.notes.trim());
340
+ }
341
+ }
342
+ const out = await pres.write({ outputType: "nodebuffer" });
343
+ return { bytes: Buffer.isBuffer(out) ? out : Buffer.from(out), slides: effective.length };
344
+ }
345
+ /**
346
+ * Add a bar / line / pie chart to a slide via pptxgenjs `addChart`. The data is
347
+ * shaped as pptxgenjs expects (one `{ name, labels, values }` per series); pie
348
+ * uses the first series only. Malformed series (empty values) are dropped, and a
349
+ * chart with nothing left to draw is skipped (never throws).
350
+ */
351
+ function addSlideChart(slide, chart) {
352
+ if (!slide.addChart)
353
+ return;
354
+ const categories = (chart.categories ?? []).map((c) => String(c ?? ""));
355
+ const allSeries = (chart.series ?? [])
356
+ .filter((s) => Array.isArray(s.values) && s.values.length > 0)
357
+ .map((s, i) => ({
358
+ name: typeof s.name === "string" && s.name.trim() ? s.name.trim() : `Series ${i + 1}`,
359
+ labels: categories,
360
+ values: s.values.map((v) => (typeof v === "number" && Number.isFinite(v) ? v : 0)),
361
+ }));
362
+ if (allSeries.length === 0)
363
+ return;
364
+ // Pie shows a single series; bar/line show all.
365
+ const data = chart.type === "pie" ? allSeries.slice(0, 1) : allSeries;
366
+ const opts = {
367
+ x: 0.7,
368
+ y: 1.6,
369
+ w: 8.6,
370
+ h: 4.4,
371
+ showLegend: data.length > 1 || chart.type === "pie",
372
+ showTitle: Boolean(chart.title && chart.title.trim()),
373
+ ...(chart.title && chart.title.trim() ? { title: chart.title.trim() } : {}),
374
+ };
375
+ slide.addChart(chart.type, data, opts);
376
+ }
377
+ /* ─────────────────────────── pdf builder ─────────────────────────── */
378
+ async function buildPdf(content, imageOpts, signal) {
379
+ const pdfLib = await import("@cantoo/pdf-lib");
380
+ const { PDFDocument, StandardFonts, rgb } = pdfLib;
381
+ const pdf = await PDFDocument.create();
382
+ // Prefer the bundled Unicode font (DejaVu Sans) so Latin/Greek/Cyrillic/accents
383
+ // render; fall back to the WinAnsi standard fonts only if the asset is missing.
384
+ let font;
385
+ let bold;
386
+ let unicodeFont = false;
387
+ try {
388
+ const uni = await embedUnicodeFont(pdf);
389
+ // DejaVu Sans ships as a single face here; use it for both weights (bold is
390
+ // approximated by the heading size, not a separate bold asset).
391
+ font = uni;
392
+ bold = uni;
393
+ unicodeFont = true;
394
+ }
395
+ catch {
396
+ font = await pdf.embedFont(StandardFonts.Helvetica);
397
+ bold = await pdf.embedFont(StandardFonts.HelveticaBold);
398
+ }
399
+ const PAGE_W = 612;
400
+ const PAGE_H = 792;
401
+ const MARGIN = 54;
402
+ const LINE = 16;
403
+ const usableW = PAGE_W - MARGIN * 2;
404
+ let page = pdf.addPage([PAGE_W, PAGE_H]);
405
+ let cursorY = PAGE_H - MARGIN;
406
+ let pageCount = 1;
407
+ const newPage = () => {
408
+ page = pdf.addPage([PAGE_W, PAGE_H]);
409
+ cursorY = PAGE_H - MARGIN;
410
+ pageCount += 1;
411
+ };
412
+ const ensure = (need) => {
413
+ if (cursorY - need < MARGIN)
414
+ newPage();
415
+ };
416
+ const drawLines = (text, size, useBold) => {
417
+ const f = useBold ? bold : font;
418
+ for (const raw of String(text ?? "").split(/\r?\n/)) {
419
+ // Strip only glyphs the chosen font lacks (with the Unicode font that
420
+ // is just CJK/emoji; with the standard-font fallback it is non-WinAnsi).
421
+ const safe = unicodeFont ? sanitizeForFont(raw, f) : stripUnsupportedGlyphs(raw);
422
+ const wrapped = wrapText(safe, f, size, usableW);
423
+ for (const line of wrapped) {
424
+ ensure(size + 4);
425
+ page.drawText(line, {
426
+ x: MARGIN,
427
+ y: cursorY - size,
428
+ size,
429
+ font: f,
430
+ color: rgb(0, 0, 0),
431
+ });
432
+ cursorY -= size + 4;
433
+ }
434
+ // Preserve blank lines as paragraph spacing.
435
+ if (wrapped.length === 0)
436
+ cursorY -= size + 4;
437
+ }
438
+ };
439
+ if (content.title && content.title.trim()) {
440
+ ensure(26);
441
+ drawLines(content.title.trim(), 22, true);
442
+ cursorY -= LINE;
443
+ }
444
+ const pages = Array.isArray(content.pages) ? content.pages : [];
445
+ for (let i = 0; i < pages.length; i++) {
446
+ const spec = pages[i];
447
+ if (!spec)
448
+ continue;
449
+ // Each spec starts a fresh page (after the first, which may carry the title).
450
+ if (i > 0 || (content.title && content.title.trim()))
451
+ newPage();
452
+ if (spec.heading && spec.heading.trim()) {
453
+ drawLines(spec.heading.trim(), 16, true);
454
+ cursorY -= 6;
455
+ }
456
+ for (const para of spec.paragraphs ?? []) {
457
+ drawLines(String(para ?? ""), 12, false);
458
+ cursorY -= 6;
459
+ }
460
+ if (spec.image && (spec.image.path || spec.image.url)) {
461
+ const img = await acquireImageForEmbed(spec.image, { ...imageOpts, ...(signal ? { signal } : {}) });
462
+ const embedded = img.format === "png" ? await pdf.embedPng(img.bytes) : await pdf.embedJpg(img.bytes);
463
+ const { width, height } = fitDimensions(img.width, img.height, usableW, 420);
464
+ ensure(height + 8);
465
+ page.drawImage(embedded, { x: MARGIN, y: cursorY - height, width, height });
466
+ cursorY -= height + 10;
467
+ }
468
+ }
469
+ // pdf-lib requires at least one page (we always added one) AND some content
470
+ // or it is still a valid empty page — fine.
471
+ void pageCount;
472
+ const out = await pdf.save();
473
+ return { bytes: Buffer.from(out), pages: pdf.getPageCount() };
474
+ }
475
+ /**
476
+ * Greedy word-wrap to fit `maxWidth` at `size` for `font`. Hard-breaks overlong
477
+ * tokens. The caller is responsible for glyph sanitation (so the Unicode-font
478
+ * path keeps Latin/Greek/Cyrillic that the WinAnsi strip would have dropped).
479
+ */
480
+ function wrapText(text, font, size, maxWidth) {
481
+ const sanitized = String(text ?? "");
482
+ if (sanitized.trim().length === 0)
483
+ return [];
484
+ const words = sanitized.split(/\s+/).filter((w) => w.length > 0);
485
+ const lines = [];
486
+ let current = "";
487
+ const widthOf = (s) => {
488
+ try {
489
+ return font.widthOfTextAtSize(s, size);
490
+ }
491
+ catch {
492
+ return s.length * size * 0.5;
493
+ }
494
+ };
495
+ for (const word of words) {
496
+ const candidate = current ? `${current} ${word}` : word;
497
+ if (widthOf(candidate) <= maxWidth) {
498
+ current = candidate;
499
+ continue;
500
+ }
501
+ if (current)
502
+ lines.push(current);
503
+ // The single word itself may exceed the width — hard-break it.
504
+ if (widthOf(word) > maxWidth) {
505
+ let chunk = "";
506
+ for (const ch of word) {
507
+ if (widthOf(chunk + ch) > maxWidth && chunk) {
508
+ lines.push(chunk);
509
+ chunk = ch;
510
+ }
511
+ else {
512
+ chunk += ch;
513
+ }
514
+ }
515
+ current = chunk;
516
+ }
517
+ else {
518
+ current = word;
519
+ }
520
+ }
521
+ if (current)
522
+ lines.push(current);
523
+ return lines;
524
+ }
525
+ /**
526
+ * The 14 PDF standard fonts are WinAnsi-encoded and throw on characters outside
527
+ * that set (e.g. emoji, CJK). Replace anything non-WinAnsi with "?" so a stray
528
+ * glyph never turns a valid call into a raw pdf-lib encode throw.
529
+ */
530
+ function stripUnsupportedGlyphs(text) {
531
+ // Keep printable ASCII + the common Latin-1 supplement range; replace the rest.
532
+ return String(text ?? "").replace(/[^\x09\x0a\x0d\x20-\x7e -ÿ]/g, "?");
533
+ }
534
+ /* ─────────────────────────── shared ─────────────────────────── */
535
+ /** Fit (w,h) inside (maxW,maxH) preserving aspect ratio; never upscales. */
536
+ function fitDimensions(w, h, maxW, maxH) {
537
+ if (w <= 0 || h <= 0)
538
+ return { width: maxW, height: maxH };
539
+ const scale = Math.min(1, maxW / w, maxH / h);
540
+ return { width: Math.max(1, Math.round(w * scale)), height: Math.max(1, Math.round(h * scale)) };
541
+ }
542
+ //# sourceMappingURL=make-document-tool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"make-document-tool.js","sourceRoot":"","sources":["../../../src/agents/tools/make-document-tool.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Tiny disk-backed LRU cache for `analyze_media` PROVIDER results.
3
+ *
4
+ * A provider understanding call (Gemini / Anthropic over the media bytes) is the
5
+ * one expensive, billable step in the tool. When the SAME bytes + question +
6
+ * provider + model + token budget are analyzed again (e.g. the operator re-asks,
7
+ * or a cron re-runs over an unchanged attachment), we can return the cached TEXT
8
+ * instead of paying for the call again.
9
+ *
10
+ * Storage model — ONE small JSON file per key under
11
+ * `resolveCacheDir()/analyze-media/`:
12
+ * • mode-aware: `resolveCacheDir()` already returns the OS cache root in
13
+ * convex/strict-zero mode (keeps `~/.brigade` clean) and the state cache dir
14
+ * in filesystem mode.
15
+ * • per-key files (not one shared file) → concurrent agents never clobber each
16
+ * other's writes; a corrupt entry only loses itself.
17
+ * • LRU bound: on write, if the directory exceeds the entry cap, the
18
+ * oldest-by-mtime files are deleted. A TTL also expires stale entries on read.
19
+ *
20
+ * The cache is BEST-EFFORT: any fs error (read, write, mkdir) is swallowed — a
21
+ * cache miss just means the provider gets called, never a tool failure.
22
+ */
23
+ /** The cached value shape. */
24
+ export interface MediaCacheValue {
25
+ text: string;
26
+ provider: string;
27
+ model: string;
28
+ }
29
+ /** Inputs that uniquely identify a provider understanding result. */
30
+ export interface MediaCacheKeyParts {
31
+ bytes: Buffer;
32
+ question: string;
33
+ provider: string;
34
+ model?: string;
35
+ maxTokens?: number;
36
+ kind: string;
37
+ }
38
+ /** Compute the cache key = sha256 over the identifying parts (hex). */
39
+ export declare function mediaCacheKey(parts: MediaCacheKeyParts): string;
40
+ /**
41
+ * Read a cached provider result. Returns `undefined` on a miss, a corrupt entry,
42
+ * or an expired entry (which is also unlinked). Never throws.
43
+ */
44
+ export declare function readMediaCache(key: string, opts?: {
45
+ ttlMs?: number;
46
+ dir?: string;
47
+ }): Promise<MediaCacheValue | undefined>;
48
+ /**
49
+ * Write a provider result to the cache + evict the oldest entries when over the
50
+ * cap. Best-effort: any failure is swallowed. Returns nothing.
51
+ */
52
+ export declare function writeMediaCache(key: string, value: MediaCacheValue, opts?: {
53
+ maxEntries?: number;
54
+ dir?: string;
55
+ }): Promise<void>;
56
+ //# sourceMappingURL=media-cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"media-cache.d.ts","sourceRoot":"","sources":["../../../src/agents/tools/media-cache.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAcH,8BAA8B;AAC9B,MAAM,WAAW,eAAe;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACd;AAED,qEAAqE;AACrE,MAAM,WAAW,kBAAkB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;CACb;AAED,uEAAuE;AACvE,wBAAgB,aAAa,CAAC,KAAK,EAAE,kBAAkB,GAAG,MAAM,CAgB/D;AAaD;;;GAGG;AACH,wBAAsB,cAAc,CACnC,GAAG,EAAE,MAAM,EACX,IAAI,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAO,GACzC,OAAO,CAAC,eAAe,GAAG,SAAS,CAAC,CA0BtC;AAED;;;GAGG;AACH,wBAAsB,eAAe,CACpC,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,eAAe,EACtB,IAAI,GAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAO,GAC9C,OAAO,CAAC,IAAI,CAAC,CA+Bf"}