@spinabot/brigade 1.8.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.
- package/README.md +21 -0
- package/dist/agents/agent-loop.d.ts +55 -0
- package/dist/agents/agent-loop.d.ts.map +1 -1
- package/dist/agents/agent-loop.js +90 -1
- package/dist/agents/agent-loop.js.map +1 -1
- package/dist/agents/channels/inbound-pipeline.d.ts +22 -0
- package/dist/agents/channels/inbound-pipeline.d.ts.map +1 -1
- package/dist/agents/channels/inbound-pipeline.js +31 -1
- package/dist/agents/channels/inbound-pipeline.js.map +1 -1
- package/dist/agents/channels/media-capture.d.ts +69 -6
- package/dist/agents/channels/media-capture.d.ts.map +1 -1
- package/dist/agents/channels/media-capture.js +125 -8
- package/dist/agents/channels/media-capture.js.map +1 -1
- package/dist/agents/channels/telegram/media.d.ts.map +1 -1
- package/dist/agents/channels/telegram/media.js +16 -4
- package/dist/agents/channels/telegram/media.js.map +1 -1
- package/dist/agents/channels/whatsapp/media.d.ts +19 -0
- package/dist/agents/channels/whatsapp/media.d.ts.map +1 -1
- package/dist/agents/channels/whatsapp/media.js +37 -2
- package/dist/agents/channels/whatsapp/media.js.map +1 -1
- package/dist/agents/media-understanding/anthropic-adapter.d.ts +49 -0
- package/dist/agents/media-understanding/anthropic-adapter.d.ts.map +1 -0
- package/dist/agents/media-understanding/anthropic-adapter.js +162 -0
- package/dist/agents/media-understanding/anthropic-adapter.js.map +1 -0
- package/dist/agents/media-understanding/config.d.ts +57 -0
- package/dist/agents/media-understanding/config.d.ts.map +1 -0
- package/dist/agents/media-understanding/config.js +289 -0
- package/dist/agents/media-understanding/config.js.map +1 -0
- package/dist/agents/media-understanding/gemini-adapter.d.ts +57 -0
- package/dist/agents/media-understanding/gemini-adapter.d.ts.map +1 -0
- package/dist/agents/media-understanding/gemini-adapter.js +343 -0
- package/dist/agents/media-understanding/gemini-adapter.js.map +1 -0
- package/dist/agents/media-understanding/index.d.ts +58 -0
- package/dist/agents/media-understanding/index.d.ts.map +1 -0
- package/dist/agents/media-understanding/index.js +275 -0
- package/dist/agents/media-understanding/index.js.map +1 -0
- package/dist/agents/media-understanding/pi-adapter.d.ts +72 -0
- package/dist/agents/media-understanding/pi-adapter.d.ts.map +1 -0
- package/dist/agents/media-understanding/pi-adapter.js +160 -0
- package/dist/agents/media-understanding/pi-adapter.js.map +1 -0
- package/dist/agents/media-understanding/types.d.ts +189 -0
- package/dist/agents/media-understanding/types.d.ts.map +1 -0
- package/dist/agents/media-understanding/types.js +51 -0
- package/dist/agents/media-understanding/types.js.map +1 -0
- package/dist/agents/session-wiring.d.ts +11 -0
- package/dist/agents/session-wiring.d.ts.map +1 -1
- package/dist/agents/session-wiring.js +1 -0
- package/dist/agents/session-wiring.js.map +1 -1
- package/dist/agents/tools/analyze-media-tool.d.ts +263 -0
- package/dist/agents/tools/analyze-media-tool.d.ts.map +1 -0
- package/dist/agents/tools/analyze-media-tool.js +2321 -0
- package/dist/agents/tools/analyze-media-tool.js.map +1 -0
- package/dist/agents/tools/doc-shared.d.ts +187 -0
- package/dist/agents/tools/doc-shared.d.ts.map +1 -0
- package/dist/agents/tools/doc-shared.js +484 -0
- package/dist/agents/tools/doc-shared.js.map +1 -0
- package/dist/agents/tools/edit-document-tool.d.ts +133 -0
- package/dist/agents/tools/edit-document-tool.d.ts.map +1 -0
- package/dist/agents/tools/edit-document-tool.js +815 -0
- package/dist/agents/tools/edit-document-tool.js.map +1 -0
- package/dist/agents/tools/image-downscale.d.ts +93 -0
- package/dist/agents/tools/image-downscale.d.ts.map +1 -0
- package/dist/agents/tools/image-downscale.js +257 -0
- package/dist/agents/tools/image-downscale.js.map +1 -0
- package/dist/agents/tools/make-document-tool.d.ts +114 -0
- package/dist/agents/tools/make-document-tool.d.ts.map +1 -0
- package/dist/agents/tools/make-document-tool.js +542 -0
- package/dist/agents/tools/make-document-tool.js.map +1 -0
- package/dist/agents/tools/media-cache.d.ts +56 -0
- package/dist/agents/tools/media-cache.d.ts.map +1 -0
- package/dist/agents/tools/media-cache.js +133 -0
- package/dist/agents/tools/media-cache.js.map +1 -0
- package/dist/agents/tools/ooxml-images.d.ts +107 -0
- package/dist/agents/tools/ooxml-images.d.ts.map +1 -0
- package/dist/agents/tools/ooxml-images.js +308 -0
- package/dist/agents/tools/ooxml-images.js.map +1 -0
- package/dist/agents/tools/registry.d.ts +12 -0
- package/dist/agents/tools/registry.d.ts.map +1 -1
- package/dist/agents/tools/registry.js +47 -0
- package/dist/agents/tools/registry.js.map +1 -1
- package/dist/buildstamp.json +1 -1
- package/dist/cli/commands/doctor.d.ts.map +1 -1
- package/dist/cli/commands/doctor.js +41 -0
- package/dist/cli/commands/doctor.js.map +1 -1
- package/dist/cli/commands/expose.d.ts +40 -0
- package/dist/cli/commands/expose.d.ts.map +1 -0
- package/dist/cli/commands/expose.js +200 -0
- package/dist/cli/commands/expose.js.map +1 -0
- package/dist/cli/program/build-program.d.ts.map +1 -1
- package/dist/cli/program/build-program.js +61 -0
- package/dist/cli/program/build-program.js.map +1 -1
- package/dist/config/io.d.ts +41 -0
- package/dist/config/io.d.ts.map +1 -1
- package/dist/config/io.js.map +1 -1
- package/dist/core/console-stream.d.ts.map +1 -1
- package/dist/core/console-stream.js +7 -5
- package/dist/core/console-stream.js.map +1 -1
- package/dist/core/server.js +6 -1
- package/dist/core/server.js.map +1 -1
- package/dist/core/tunnel/auth-proxy.d.ts +55 -0
- package/dist/core/tunnel/auth-proxy.d.ts.map +1 -0
- package/dist/core/tunnel/auth-proxy.js +179 -0
- package/dist/core/tunnel/auth-proxy.js.map +1 -0
- package/dist/core/tunnel/manager.d.ts +42 -0
- package/dist/core/tunnel/manager.d.ts.map +1 -0
- package/dist/core/tunnel/manager.js +102 -0
- package/dist/core/tunnel/manager.js.map +1 -0
- package/dist/core/tunnel/providers/bore.d.ts +18 -0
- package/dist/core/tunnel/providers/bore.d.ts.map +1 -0
- package/dist/core/tunnel/providers/bore.js +117 -0
- package/dist/core/tunnel/providers/bore.js.map +1 -0
- package/dist/core/tunnel/providers/cloudflared.d.ts +24 -0
- package/dist/core/tunnel/providers/cloudflared.d.ts.map +1 -0
- package/dist/core/tunnel/providers/cloudflared.js +179 -0
- package/dist/core/tunnel/providers/cloudflared.js.map +1 -0
- package/dist/core/tunnel/providers/custom.d.ts +21 -0
- package/dist/core/tunnel/providers/custom.d.ts.map +1 -0
- package/dist/core/tunnel/providers/custom.js +124 -0
- package/dist/core/tunnel/providers/custom.js.map +1 -0
- package/dist/core/tunnel/registry.d.ts +15 -0
- package/dist/core/tunnel/registry.d.ts.map +1 -0
- package/dist/core/tunnel/registry.js +26 -0
- package/dist/core/tunnel/registry.js.map +1 -0
- package/dist/core/tunnel/state.d.ts +39 -0
- package/dist/core/tunnel/state.d.ts.map +1 -0
- package/dist/core/tunnel/state.js +57 -0
- package/dist/core/tunnel/state.js.map +1 -0
- package/dist/core/tunnel/types.d.ts +61 -0
- package/dist/core/tunnel/types.d.ts.map +1 -0
- package/dist/core/tunnel/types.js +20 -0
- package/dist/core/tunnel/types.js.map +1 -0
- package/dist/system-prompt/assembler.d.ts.map +1 -1
- package/dist/system-prompt/assembler.js +25 -1
- package/dist/system-prompt/assembler.js.map +1 -1
- package/dist/system-prompt/guidance.d.ts +30 -0
- package/dist/system-prompt/guidance.d.ts.map +1 -1
- package/dist/system-prompt/guidance.js +50 -0
- package/dist/system-prompt/guidance.js.map +1 -1
- package/package.json +13 -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"}
|