@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.
Files changed (139) hide show
  1. package/README.md +21 -0
  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/cli/commands/expose.d.ts +40 -0
  86. package/dist/cli/commands/expose.d.ts.map +1 -0
  87. package/dist/cli/commands/expose.js +200 -0
  88. package/dist/cli/commands/expose.js.map +1 -0
  89. package/dist/cli/program/build-program.d.ts.map +1 -1
  90. package/dist/cli/program/build-program.js +61 -0
  91. package/dist/cli/program/build-program.js.map +1 -1
  92. package/dist/config/io.d.ts +41 -0
  93. package/dist/config/io.d.ts.map +1 -1
  94. package/dist/config/io.js.map +1 -1
  95. package/dist/core/console-stream.d.ts.map +1 -1
  96. package/dist/core/console-stream.js +7 -5
  97. package/dist/core/console-stream.js.map +1 -1
  98. package/dist/core/server.js +6 -1
  99. package/dist/core/server.js.map +1 -1
  100. package/dist/core/tunnel/auth-proxy.d.ts +55 -0
  101. package/dist/core/tunnel/auth-proxy.d.ts.map +1 -0
  102. package/dist/core/tunnel/auth-proxy.js +179 -0
  103. package/dist/core/tunnel/auth-proxy.js.map +1 -0
  104. package/dist/core/tunnel/manager.d.ts +42 -0
  105. package/dist/core/tunnel/manager.d.ts.map +1 -0
  106. package/dist/core/tunnel/manager.js +102 -0
  107. package/dist/core/tunnel/manager.js.map +1 -0
  108. package/dist/core/tunnel/providers/bore.d.ts +18 -0
  109. package/dist/core/tunnel/providers/bore.d.ts.map +1 -0
  110. package/dist/core/tunnel/providers/bore.js +117 -0
  111. package/dist/core/tunnel/providers/bore.js.map +1 -0
  112. package/dist/core/tunnel/providers/cloudflared.d.ts +24 -0
  113. package/dist/core/tunnel/providers/cloudflared.d.ts.map +1 -0
  114. package/dist/core/tunnel/providers/cloudflared.js +179 -0
  115. package/dist/core/tunnel/providers/cloudflared.js.map +1 -0
  116. package/dist/core/tunnel/providers/custom.d.ts +21 -0
  117. package/dist/core/tunnel/providers/custom.d.ts.map +1 -0
  118. package/dist/core/tunnel/providers/custom.js +124 -0
  119. package/dist/core/tunnel/providers/custom.js.map +1 -0
  120. package/dist/core/tunnel/registry.d.ts +15 -0
  121. package/dist/core/tunnel/registry.d.ts.map +1 -0
  122. package/dist/core/tunnel/registry.js +26 -0
  123. package/dist/core/tunnel/registry.js.map +1 -0
  124. package/dist/core/tunnel/state.d.ts +39 -0
  125. package/dist/core/tunnel/state.d.ts.map +1 -0
  126. package/dist/core/tunnel/state.js +57 -0
  127. package/dist/core/tunnel/state.js.map +1 -0
  128. package/dist/core/tunnel/types.d.ts +61 -0
  129. package/dist/core/tunnel/types.d.ts.map +1 -0
  130. package/dist/core/tunnel/types.js +20 -0
  131. package/dist/core/tunnel/types.js.map +1 -0
  132. package/dist/system-prompt/assembler.d.ts.map +1 -1
  133. package/dist/system-prompt/assembler.js +25 -1
  134. package/dist/system-prompt/assembler.js.map +1 -1
  135. package/dist/system-prompt/guidance.d.ts +30 -0
  136. package/dist/system-prompt/guidance.d.ts.map +1 -1
  137. package/dist/system-prompt/guidance.js +50 -0
  138. package/dist/system-prompt/guidance.js.map +1 -1
  139. package/package.json +13 -1
@@ -0,0 +1,133 @@
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
+ import { createHash } from "node:crypto";
24
+ import fs from "node:fs";
25
+ import fsp from "node:fs/promises";
26
+ import path from "node:path";
27
+ import { resolveCacheDir } from "../../config/paths.js";
28
+ /** Max entries kept on disk before LRU eviction (by mtime). */
29
+ const DEFAULT_MAX_ENTRIES = 200;
30
+ /** Entry TTL — a cached provider answer older than this is ignored + cleaned. */
31
+ const DEFAULT_TTL_MS = 7 * 24 * 60 * 60 * 1000; // 7 days
32
+ /** Compute the cache key = sha256 over the identifying parts (hex). */
33
+ export function mediaCacheKey(parts) {
34
+ const h = createHash("sha256");
35
+ h.update(parts.kind);
36
+ h.update("\0");
37
+ h.update(parts.provider);
38
+ h.update("\0");
39
+ h.update(parts.model ?? "");
40
+ h.update("\0");
41
+ h.update(String(parts.maxTokens ?? ""));
42
+ h.update("\0");
43
+ h.update(parts.question);
44
+ h.update("\0");
45
+ // Hash the bytes last (largest input). The content hash is what makes the
46
+ // key change when the underlying media changes.
47
+ h.update(parts.bytes);
48
+ return h.digest("hex");
49
+ }
50
+ /** Resolve (and lazily create) the cache directory. Returns undefined on failure. */
51
+ function cacheDir() {
52
+ try {
53
+ const dir = path.join(resolveCacheDir(), "analyze-media");
54
+ fs.mkdirSync(dir, { recursive: true });
55
+ return dir;
56
+ }
57
+ catch {
58
+ return undefined;
59
+ }
60
+ }
61
+ /**
62
+ * Read a cached provider result. Returns `undefined` on a miss, a corrupt entry,
63
+ * or an expired entry (which is also unlinked). Never throws.
64
+ */
65
+ export async function readMediaCache(key, opts = {}) {
66
+ const dir = opts.dir ?? cacheDir();
67
+ if (!dir)
68
+ return undefined;
69
+ const file = path.join(dir, `${key}.json`);
70
+ try {
71
+ const stat = await fsp.stat(file);
72
+ const ttl = opts.ttlMs ?? DEFAULT_TTL_MS;
73
+ if (Date.now() - stat.mtimeMs > ttl) {
74
+ void fsp.unlink(file).catch(() => { });
75
+ return undefined;
76
+ }
77
+ const raw = await fsp.readFile(file, "utf8");
78
+ const parsed = JSON.parse(raw);
79
+ if (typeof parsed.text === "string" && parsed.text.length > 0) {
80
+ // Touch mtime so LRU treats a cache HIT as recently-used.
81
+ void fsp.utimes(file, new Date(), new Date()).catch(() => { });
82
+ return {
83
+ text: parsed.text,
84
+ provider: typeof parsed.provider === "string" ? parsed.provider : "",
85
+ model: typeof parsed.model === "string" ? parsed.model : "",
86
+ };
87
+ }
88
+ }
89
+ catch {
90
+ /* miss / corrupt / unreadable → undefined */
91
+ }
92
+ return undefined;
93
+ }
94
+ /**
95
+ * Write a provider result to the cache + evict the oldest entries when over the
96
+ * cap. Best-effort: any failure is swallowed. Returns nothing.
97
+ */
98
+ export async function writeMediaCache(key, value, opts = {}) {
99
+ const dir = opts.dir ?? cacheDir();
100
+ if (!dir)
101
+ return;
102
+ const file = path.join(dir, `${key}.json`);
103
+ try {
104
+ await fsp.writeFile(file, JSON.stringify(value), "utf8");
105
+ }
106
+ catch {
107
+ return; // could not persist — give up silently
108
+ }
109
+ // LRU eviction: if the directory holds more than the cap, delete the oldest
110
+ // by mtime. Cheap (a stat per entry) and only runs on writes.
111
+ try {
112
+ const max = opts.maxEntries ?? DEFAULT_MAX_ENTRIES;
113
+ const names = (await fsp.readdir(dir)).filter((n) => n.endsWith(".json"));
114
+ if (names.length <= max)
115
+ return;
116
+ const stats = await Promise.all(names.map(async (n) => {
117
+ try {
118
+ const s = await fsp.stat(path.join(dir, n));
119
+ return { n, mtime: s.mtimeMs };
120
+ }
121
+ catch {
122
+ return { n, mtime: 0 };
123
+ }
124
+ }));
125
+ stats.sort((a, b) => a.mtime - b.mtime); // oldest first
126
+ const toDelete = stats.slice(0, names.length - max);
127
+ await Promise.all(toDelete.map((e) => fsp.unlink(path.join(dir, e.n)).catch(() => { })));
128
+ }
129
+ catch {
130
+ /* eviction is best-effort */
131
+ }
132
+ }
133
+ //# sourceMappingURL=media-cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"media-cache.js","sourceRoot":"","sources":["../../../src/agents/tools/media-cache.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,107 @@
1
+ /**
2
+ * Embedded-image extraction for OOXML documents (PPTX / DOCX / XLSX) — the
3
+ * "see the wireframes inside the deck" half of `analyze_media`.
4
+ *
5
+ * ─────────────────────────────────────────────────────────────────────────
6
+ * WHY THIS MODULE (read before changing)
7
+ * ─────────────────────────────────────────────────────────────────────────
8
+ * `analyze_media`'s OOXML readers return only the document TEXT (slide titles,
9
+ * paragraph runs, cell strings). But a real deck carries its substance in the
10
+ * PICTURES — wireframes, screenshots, diagrams, charts rendered to images. Asked
11
+ * to "go through the wireframe images in this .pptx", the agent used to have to
12
+ * shell out to `python zipfile` to pull `ppt/media/*.png`, then re-run
13
+ * `analyze_media` on each PNG. This module closes that gap: it extracts the
14
+ * embedded raster images straight from the already-unzipped OOXML entries the
15
+ * reader has in hand, so the tool can route them through the SAME image path it
16
+ * already uses (image blocks on a vision model / a provider on a text-only one).
17
+ *
18
+ * ─────────────────────────────────────────────────────────────────────────
19
+ * SLIDE / PAGE SCOPING (the important part for PPTX)
20
+ * ─────────────────────────────────────────────────────────────────────────
21
+ * A PPTX maps images to slides through the relationship graph, NOT by filename:
22
+ * presentation.xml → <p:sldId r:id="rIdN"/> in PRESENTATION order
23
+ * presentation.xml.rels → rIdN → ppt/slides/slideK.xml
24
+ * slideK.xml.rels → rIdM → ../media/imageX.png (that slide's images)
25
+ * So slide N's images are exactly the `../media/*` targets in that slide's rels
26
+ * file — which is what the manual workaround discovered ("SLIDE 8 rId3
27
+ * ../media/image16.png"). We resolve slides in presentation order, then honour
28
+ * the existing `pages` range over THAT order, returning only the selected
29
+ * slides' images. (Image filename numbering does NOT track slide order, so a
30
+ * filename-only approach would scope wrong — we never use it for PPTX.)
31
+ *
32
+ * DOCX/XLSX have no robust per-page image mapping (a Word page is a layout-time
33
+ * concept, not in the XML), so we return ALL embedded images (capped) when no
34
+ * scope applies — the `pages` range is honoured only for PPTX.
35
+ *
36
+ * ─────────────────────────────────────────────────────────────────────────
37
+ * UNSUPPORTED EMBEDS
38
+ * ─────────────────────────────────────────────────────────────────────────
39
+ * Only provider-DECODABLE raster types are surfaced (png/jpeg/gif/webp/bmp/
40
+ * tiff). Vector / exotic embeds — `.emf` / `.wmf` (Windows metafiles) and
41
+ * `.wdp` (JPEG-XR / HD Photo) — cannot be decoded without a native dep, so they
42
+ * are SKIPPED with a count (the real failure case hit `hdphoto1.wdp`). The
43
+ * caller reports "N image(s) skipped (unsupported format)" rather than throwing.
44
+ *
45
+ * Pure functions over an already-unzipped entry map; no I/O, no provider calls.
46
+ */
47
+ /** An embedded image pulled out of an OOXML document. */
48
+ export interface ExtractedOoxmlImage {
49
+ /** Zip entry name, e.g. `ppt/media/image16.png`. */
50
+ entry: string;
51
+ /** Raw image bytes. */
52
+ bytes: Buffer;
53
+ /** Detected MIME (always a provider-decodable raster type). */
54
+ mime: string;
55
+ /** 1-indexed slide number (PPTX only) when the image is mapped to a slide. */
56
+ slide?: number;
57
+ /** Human label, e.g. "slide 8 image 1" or "image 1". */
58
+ label: string;
59
+ }
60
+ /** Result of an extraction pass. */
61
+ export interface OoxmlImageExtraction {
62
+ /** Images selected (after `pages` scoping) and within the cap. */
63
+ images: ExtractedOoxmlImage[];
64
+ /** How many decodable images matched the scope BEFORE the cap (for "N of M"). */
65
+ matched: number;
66
+ /** How many embeds were skipped because their format is not decodable. */
67
+ skipped: number;
68
+ }
69
+ /**
70
+ * Resolve a relationship Target (relative to a `_rels` file's owning part)
71
+ * against a base directory, collapsing `../` and `./` segments. E.g. base
72
+ * `ppt/slides/` + target `../media/image1.png` → `ppt/media/image1.png`.
73
+ */
74
+ export declare function resolveRelTarget(baseDir: string, target: string): string;
75
+ /**
76
+ * Parse a `.rels` XML blob into `[ {id, target} ]`. Tolerant of attribute order
77
+ * (Id before/after Target) and self-closing `<Relationship .../>`.
78
+ */
79
+ export declare function parseRelationships(xml: string): Array<{
80
+ id: string;
81
+ target: string;
82
+ }>;
83
+ /**
84
+ * Resolve slide part paths in PRESENTATION order from `presentation.xml` +
85
+ * `presentation.xml.rels`. Returns `[]` when the presentation graph can't be
86
+ * read (the caller then falls back to filename order).
87
+ */
88
+ export declare function resolveSlideOrder(entries: Record<string, Uint8Array>): string[];
89
+ /**
90
+ * Extract embedded images from already-unzipped OOXML entries.
91
+ *
92
+ * • PPTX: resolves slide order via the presentation graph and maps images to
93
+ * slides through each slide's rels; honours `inRange` over slide position.
94
+ * Falls back to filename order (all slides) when the graph is unreadable.
95
+ * • DOCX/XLSX: returns all media-folder images (no page scoping).
96
+ *
97
+ * `inRange(slideNum)` is the page-range predicate (from `parsePageRange`) and is
98
+ * applied to PPTX SLIDE numbers only. `cap` bounds the number of images RETURNED
99
+ * (the per-call image cap); `matched` reports how many decodable images were in
100
+ * scope before the cap so the caller can say "showing N of M". `skipped` counts
101
+ * undecodable embeds in scope.
102
+ */
103
+ export declare function extractOoxmlImages(entries: Record<string, Uint8Array>, kind: "pptx" | "docx" | "xlsx", opts: {
104
+ inRange?: (slideNum: number) => boolean;
105
+ cap: number;
106
+ }): OoxmlImageExtraction;
107
+ //# sourceMappingURL=ooxml-images.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ooxml-images.d.ts","sourceRoot":"","sources":["../../../src/agents/tools/ooxml-images.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AAEH,yDAAyD;AACzD,MAAM,WAAW,mBAAmB;IACnC,oDAAoD;IACpD,KAAK,EAAE,MAAM,CAAC;IACd,uBAAuB;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,+DAA+D;IAC/D,IAAI,EAAE,MAAM,CAAC;IACb,8EAA8E;IAC9E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wDAAwD;IACxD,KAAK,EAAE,MAAM,CAAC;CACd;AAED,oCAAoC;AACpC,MAAM,WAAW,oBAAoB;IACpC,kEAAkE;IAClE,MAAM,EAAE,mBAAmB,EAAE,CAAC;IAC9B,iFAAiF;IACjF,OAAO,EAAE,MAAM,CAAC;IAChB,0EAA0E;IAC1E,OAAO,EAAE,MAAM,CAAC;CAChB;AAkDD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAYxE;AAuBD;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,KAAK,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAWrF;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,GAAG,MAAM,EAAE,CAmB/E;AAuDD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,kBAAkB,CACjC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,EACnC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,EAC9B,IAAI,EAAE;IAAE,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAC5D,oBAAoB,CA0DtB"}
@@ -0,0 +1,308 @@
1
+ /**
2
+ * Embedded-image extraction for OOXML documents (PPTX / DOCX / XLSX) — the
3
+ * "see the wireframes inside the deck" half of `analyze_media`.
4
+ *
5
+ * ─────────────────────────────────────────────────────────────────────────
6
+ * WHY THIS MODULE (read before changing)
7
+ * ─────────────────────────────────────────────────────────────────────────
8
+ * `analyze_media`'s OOXML readers return only the document TEXT (slide titles,
9
+ * paragraph runs, cell strings). But a real deck carries its substance in the
10
+ * PICTURES — wireframes, screenshots, diagrams, charts rendered to images. Asked
11
+ * to "go through the wireframe images in this .pptx", the agent used to have to
12
+ * shell out to `python zipfile` to pull `ppt/media/*.png`, then re-run
13
+ * `analyze_media` on each PNG. This module closes that gap: it extracts the
14
+ * embedded raster images straight from the already-unzipped OOXML entries the
15
+ * reader has in hand, so the tool can route them through the SAME image path it
16
+ * already uses (image blocks on a vision model / a provider on a text-only one).
17
+ *
18
+ * ─────────────────────────────────────────────────────────────────────────
19
+ * SLIDE / PAGE SCOPING (the important part for PPTX)
20
+ * ─────────────────────────────────────────────────────────────────────────
21
+ * A PPTX maps images to slides through the relationship graph, NOT by filename:
22
+ * presentation.xml → <p:sldId r:id="rIdN"/> in PRESENTATION order
23
+ * presentation.xml.rels → rIdN → ppt/slides/slideK.xml
24
+ * slideK.xml.rels → rIdM → ../media/imageX.png (that slide's images)
25
+ * So slide N's images are exactly the `../media/*` targets in that slide's rels
26
+ * file — which is what the manual workaround discovered ("SLIDE 8 rId3
27
+ * ../media/image16.png"). We resolve slides in presentation order, then honour
28
+ * the existing `pages` range over THAT order, returning only the selected
29
+ * slides' images. (Image filename numbering does NOT track slide order, so a
30
+ * filename-only approach would scope wrong — we never use it for PPTX.)
31
+ *
32
+ * DOCX/XLSX have no robust per-page image mapping (a Word page is a layout-time
33
+ * concept, not in the XML), so we return ALL embedded images (capped) when no
34
+ * scope applies — the `pages` range is honoured only for PPTX.
35
+ *
36
+ * ─────────────────────────────────────────────────────────────────────────
37
+ * UNSUPPORTED EMBEDS
38
+ * ─────────────────────────────────────────────────────────────────────────
39
+ * Only provider-DECODABLE raster types are surfaced (png/jpeg/gif/webp/bmp/
40
+ * tiff). Vector / exotic embeds — `.emf` / `.wmf` (Windows metafiles) and
41
+ * `.wdp` (JPEG-XR / HD Photo) — cannot be decoded without a native dep, so they
42
+ * are SKIPPED with a count (the real failure case hit `hdphoto1.wdp`). The
43
+ * caller reports "N image(s) skipped (unsupported format)" rather than throwing.
44
+ *
45
+ * Pure functions over an already-unzipped entry map; no I/O, no provider calls.
46
+ */
47
+ /**
48
+ * Extensions of embedded media that providers / jimp can decode. Everything
49
+ * else (`emf`/`wmf` vector metafiles, `wdp` JPEG-XR) is skipped — see header.
50
+ */
51
+ const DECODABLE_EXT_MIME = {
52
+ png: "image/png",
53
+ jpg: "image/jpeg",
54
+ jpeg: "image/jpeg",
55
+ jpe: "image/jpeg",
56
+ gif: "image/gif",
57
+ webp: "image/webp",
58
+ bmp: "image/bmp",
59
+ tif: "image/tiff",
60
+ tiff: "image/tiff",
61
+ };
62
+ /** Lowercase extension (no dot) of a zip entry path. */
63
+ function entryExt(name) {
64
+ const dot = name.lastIndexOf(".");
65
+ if (dot < 0)
66
+ return "";
67
+ return name.slice(dot + 1).toLowerCase();
68
+ }
69
+ /** The media directory prefix for each OOXML kind. */
70
+ function mediaPrefix(kind) {
71
+ switch (kind) {
72
+ case "pptx":
73
+ return "ppt/media/";
74
+ case "docx":
75
+ return "word/media/";
76
+ case "xlsx":
77
+ return "xl/media/";
78
+ }
79
+ }
80
+ /**
81
+ * Decode `&amp;`-style entities just enough to compare relationship targets
82
+ * (targets rarely contain entities, but `&amp;` in a path would otherwise miss).
83
+ */
84
+ function decodeRelTarget(s) {
85
+ return s
86
+ .replace(/&amp;/g, "&")
87
+ .replace(/&lt;/g, "<")
88
+ .replace(/&gt;/g, ">")
89
+ .replace(/&quot;/g, '"')
90
+ .replace(/&apos;/g, "'");
91
+ }
92
+ /**
93
+ * Resolve a relationship Target (relative to a `_rels` file's owning part)
94
+ * against a base directory, collapsing `../` and `./` segments. E.g. base
95
+ * `ppt/slides/` + target `../media/image1.png` → `ppt/media/image1.png`.
96
+ */
97
+ export function resolveRelTarget(baseDir, target) {
98
+ const t = decodeRelTarget(target.trim()).replace(/^\/+/, "");
99
+ // Absolute-within-package targets (start with "/") resolve from the root.
100
+ const fromRoot = target.trim().startsWith("/");
101
+ const baseParts = fromRoot ? [] : baseDir.split("/").filter(Boolean);
102
+ const parts = [...baseParts];
103
+ for (const seg of t.split("/")) {
104
+ if (seg === "" || seg === ".")
105
+ continue;
106
+ if (seg === "..")
107
+ parts.pop();
108
+ else
109
+ parts.push(seg);
110
+ }
111
+ return parts.join("/");
112
+ }
113
+ /** Directory portion of a part path (e.g. `ppt/slides/slide1.xml` → `ppt/slides`). */
114
+ function partDir(part) {
115
+ const slash = part.lastIndexOf("/");
116
+ return slash < 0 ? "" : part.slice(0, slash);
117
+ }
118
+ /** The `_rels` sidecar path for a part (e.g. `ppt/slides/slide1.xml` → `ppt/slides/_rels/slide1.xml.rels`). */
119
+ function relsPathFor(part) {
120
+ const dir = partDir(part);
121
+ const file = part.slice(dir.length ? dir.length + 1 : 0);
122
+ return `${dir ? dir + "/" : ""}_rels/${file}.rels`;
123
+ }
124
+ /** Decode a zip entry to a UTF-8 string (entries are Uint8Array). */
125
+ function entryToString(entries, name) {
126
+ const u8 = entries[name];
127
+ if (!u8)
128
+ return undefined;
129
+ // Avoid a fflate import here (keep this module pure/sync); TextDecoder handles UTF-8.
130
+ return new TextDecoder("utf-8").decode(u8);
131
+ }
132
+ /**
133
+ * Parse a `.rels` XML blob into `[ {id, target} ]`. Tolerant of attribute order
134
+ * (Id before/after Target) and self-closing `<Relationship .../>`.
135
+ */
136
+ export function parseRelationships(xml) {
137
+ const out = [];
138
+ const relRe = /<Relationship\b([^>]*?)\/?>/g;
139
+ let m;
140
+ while ((m = relRe.exec(xml)) !== null) {
141
+ const attrs = m[1] ?? "";
142
+ const id = /\bId="([^"]*)"/.exec(attrs)?.[1];
143
+ const target = /\bTarget="([^"]*)"/.exec(attrs)?.[1];
144
+ if (id && target)
145
+ out.push({ id, target });
146
+ }
147
+ return out;
148
+ }
149
+ /**
150
+ * Resolve slide part paths in PRESENTATION order from `presentation.xml` +
151
+ * `presentation.xml.rels`. Returns `[]` when the presentation graph can't be
152
+ * read (the caller then falls back to filename order).
153
+ */
154
+ export function resolveSlideOrder(entries) {
155
+ const presXml = entryToString(entries, "ppt/presentation.xml");
156
+ const relsXml = entryToString(entries, "ppt/_rels/presentation.xml.rels");
157
+ if (!presXml || !relsXml)
158
+ return [];
159
+ const idToTarget = new Map();
160
+ for (const rel of parseRelationships(relsXml))
161
+ idToTarget.set(rel.id, rel.target);
162
+ const order = [];
163
+ // <p:sldId id="256" r:id="rId2"/> — the r:id ordering IS the slide order.
164
+ const sldIdRe = /<p:sldId\b[^>]*\br:id="([^"]+)"[^>]*\/?>/g;
165
+ let m;
166
+ while ((m = sldIdRe.exec(presXml)) !== null) {
167
+ const rId = m[1];
168
+ const target = idToTarget.get(rId);
169
+ if (!target)
170
+ continue;
171
+ // presentation.xml lives in ppt/, so targets resolve from ppt/.
172
+ const resolved = resolveRelTarget("ppt", target);
173
+ if (entries[resolved])
174
+ order.push(resolved);
175
+ }
176
+ return order;
177
+ }
178
+ /**
179
+ * Map each slide part to the decodable `../media/*` images it references, in
180
+ * presentation order. Returns one entry per slide (slide 1-indexed by position
181
+ * in `slideOrder`). Each slide's images preserve their reference order.
182
+ */
183
+ function imagesPerSlide(entries, slideOrder) {
184
+ const result = [];
185
+ for (let i = 0; i < slideOrder.length; i++) {
186
+ const slidePart = slideOrder[i];
187
+ const relsXml = entryToString(entries, relsPathFor(slidePart));
188
+ const imgs = [];
189
+ if (relsXml) {
190
+ const base = partDir(slidePart);
191
+ for (const rel of parseRelationships(relsXml)) {
192
+ const resolved = resolveRelTarget(base, rel.target);
193
+ if (!resolved.startsWith("ppt/media/"))
194
+ continue;
195
+ if (!(resolved in entries))
196
+ continue;
197
+ if (!DECODABLE_EXT_MIME[entryExt(resolved)] && !isSkippableMedia(resolved))
198
+ continue;
199
+ imgs.push(resolved);
200
+ }
201
+ }
202
+ result.push({ slide: i + 1, entries: imgs });
203
+ }
204
+ return result;
205
+ }
206
+ /** True when a media entry is a known-but-undecodable embed (emf/wmf/wdp/svg/…). */
207
+ function isSkippableMedia(entry) {
208
+ const ext = entryExt(entry);
209
+ return ext === "emf" || ext === "wmf" || ext === "wdp" || ext === "svg" || ext === "emz" || ext === "wmz";
210
+ }
211
+ /** All `<prefix>media/*` entries in stable (numeric-aware) name order. */
212
+ function allMediaEntries(entries, prefix) {
213
+ return Object.keys(entries)
214
+ .filter((n) => n.startsWith(prefix) && entryExt(n).length > 0)
215
+ .sort(numericAwareCompare);
216
+ }
217
+ /** Sort `image2.png` before `image10.png` (numeric-aware on the trailing number). */
218
+ function numericAwareCompare(a, b) {
219
+ const na = /(\d+)\.[^.]+$/.exec(a);
220
+ const nb = /(\d+)\.[^.]+$/.exec(b);
221
+ if (na && nb) {
222
+ const d = parseInt(na[1], 10) - parseInt(nb[1], 10);
223
+ if (d !== 0)
224
+ return d;
225
+ }
226
+ return a < b ? -1 : a > b ? 1 : 0;
227
+ }
228
+ /**
229
+ * Extract embedded images from already-unzipped OOXML entries.
230
+ *
231
+ * • PPTX: resolves slide order via the presentation graph and maps images to
232
+ * slides through each slide's rels; honours `inRange` over slide position.
233
+ * Falls back to filename order (all slides) when the graph is unreadable.
234
+ * • DOCX/XLSX: returns all media-folder images (no page scoping).
235
+ *
236
+ * `inRange(slideNum)` is the page-range predicate (from `parsePageRange`) and is
237
+ * applied to PPTX SLIDE numbers only. `cap` bounds the number of images RETURNED
238
+ * (the per-call image cap); `matched` reports how many decodable images were in
239
+ * scope before the cap so the caller can say "showing N of M". `skipped` counts
240
+ * undecodable embeds in scope.
241
+ */
242
+ export function extractOoxmlImages(entries, kind, opts) {
243
+ const prefix = mediaPrefix(kind);
244
+ const inRange = opts.inRange ?? (() => true);
245
+ // Build the ordered, scoped list of candidate entries (+ slide map for pptx).
246
+ const ordered = [];
247
+ if (kind === "pptx") {
248
+ const slideOrder = resolveSlideOrder(entries);
249
+ if (slideOrder.length > 0) {
250
+ const perSlide = imagesPerSlide(entries, slideOrder);
251
+ const seen = new Set();
252
+ for (const { slide, entries: imgs } of perSlide) {
253
+ if (!inRange(slide))
254
+ continue;
255
+ for (const e of imgs) {
256
+ // An image shared across slides (rare) is attributed to its FIRST
257
+ // in-scope slide to avoid duplicate blocks.
258
+ if (seen.has(e))
259
+ continue;
260
+ seen.add(e);
261
+ ordered.push({ entry: e, slide });
262
+ }
263
+ }
264
+ }
265
+ else {
266
+ // Presentation graph unreadable → fall back to every media file (no slide
267
+ // scoping possible). This keeps a malformed-but-openable deck working.
268
+ for (const e of allMediaEntries(entries, prefix))
269
+ ordered.push({ entry: e });
270
+ }
271
+ }
272
+ else {
273
+ for (const e of allMediaEntries(entries, prefix))
274
+ ordered.push({ entry: e });
275
+ }
276
+ // Partition into decodable (kept) vs skippable (counted), then apply the cap.
277
+ let matched = 0;
278
+ let skipped = 0;
279
+ const images = [];
280
+ const perSlideSeq = new Map();
281
+ for (const cand of ordered) {
282
+ const mime = DECODABLE_EXT_MIME[entryExt(cand.entry)];
283
+ if (!mime) {
284
+ if (isSkippableMedia(cand.entry))
285
+ skipped += 1;
286
+ continue;
287
+ }
288
+ matched += 1;
289
+ if (images.length >= opts.cap)
290
+ continue; // count toward `matched`, don't emit
291
+ const u8 = entries[cand.entry];
292
+ if (!u8)
293
+ continue;
294
+ const slideKey = cand.slide ?? "none";
295
+ const seq = (perSlideSeq.get(slideKey) ?? 0) + 1;
296
+ perSlideSeq.set(slideKey, seq);
297
+ const label = cand.slide ? `slide ${cand.slide} image ${seq}` : `image ${seq}`;
298
+ images.push({
299
+ entry: cand.entry,
300
+ bytes: Buffer.from(u8),
301
+ mime,
302
+ ...(cand.slide ? { slide: cand.slide } : {}),
303
+ label,
304
+ });
305
+ }
306
+ return { images, matched, skipped };
307
+ }
308
+ //# sourceMappingURL=ooxml-images.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ooxml-images.js","sourceRoot":"","sources":["../../../src/agents/tools/ooxml-images.ts"],"names":[],"mappings":"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"}
@@ -99,6 +99,18 @@ export interface CreateBrigadeToolsOptions {
99
99
  * narrow per-call gate kicks in.
100
100
  */
101
101
  senderIsOwner?: boolean;
102
+ /**
103
+ * Resolved turn-model context (provider + modelId of the model driving this
104
+ * turn). Threaded into `analyze_media` so it can decide whether returning an
105
+ * IMAGE content block is meaningful (a text-only model can't consume one).
106
+ * Optional — when omitted (tests / legacy call sites) the tool assumes the
107
+ * model is vision-capable but annotates the uncertainty.
108
+ */
109
+ modelContext?: {
110
+ provider?: string;
111
+ modelId?: string;
112
+ imageInput?: boolean;
113
+ };
102
114
  /**
103
115
  * Per-turn session metadata (Step 11's `SessionContext`). When supplied,
104
116
  * `createBrigadeTools` includes the four sessions tools
@@ -1 +1 @@
1
- {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/agents/tools/registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAGH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAC;AAC3E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AA0C5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,WAAW,yBAAyB;IACzC,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ;;;;;;OAMG;IACH,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC;;;;;;;;;OASG;IACH,eAAe,CAAC,EAAE;QACjB,uEAAuE;QACvE,gBAAgB,EAAE,MAAM,CAAC;QACzB,2DAA2D;QAC3D,WAAW,EAAE,MAAM,CAAC;QACpB,2CAA2C;QAC3C,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,oEAAoE;QACpE,YAAY,CAAC,EAAE,WAAW,CAAC;QAC3B;;;WAGG;QACH,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,aAAa,CAAC,EAAE,MAAM,CAAC;KACvB,CAAC;IACF,0EAA0E;IAC1E,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;;;;;;;;;;OAYG;IACH,cAAc,CAAC,EAAE,oBAAoB,CAAC;IACtC;;;;;;OAMG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;;;;;OAOG;IACH,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC;;;;OAIG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE;QACnB,UAAU,CAAC,EAAE,OAAO,sBAAsB,EAAE,sBAAsB,CAAC;QACnE,SAAS,CAAC,EAAE,OAAO,sBAAsB,EAAE,kBAAkB,CAAC;QAC9D,WAAW,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;KAClC,CAAC;CACF;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,yBAAyB,GAAG,cAAc,EAAE,CA0YpF;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,EAAE,CAE/C"}
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/agents/tools/registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAGH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAC;AAC3E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AA6C5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,WAAW,yBAAyB;IACzC,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ;;;;;;OAMG;IACH,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC;;;;;;;;;OASG;IACH,eAAe,CAAC,EAAE;QACjB,uEAAuE;QACvE,gBAAgB,EAAE,MAAM,CAAC;QACzB,2DAA2D;QAC3D,WAAW,EAAE,MAAM,CAAC;QACpB,2CAA2C;QAC3C,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,oEAAoE;QACpE,YAAY,CAAC,EAAE,WAAW,CAAC;QAC3B;;;WAGG;QACH,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,aAAa,CAAC,EAAE,MAAM,CAAC;KACvB,CAAC;IACF,0EAA0E;IAC1E,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;;;;;;;;;;OAYG;IACH,cAAc,CAAC,EAAE,oBAAoB,CAAC;IACtC;;;;;;OAMG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;;;;OAMG;IACH,YAAY,CAAC,EAAE;QACd,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,UAAU,CAAC,EAAE,OAAO,CAAC;KACrB,CAAC;IACF;;;;;;;OAOG;IACH,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC;;;;OAIG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE;QACnB,UAAU,CAAC,EAAE,OAAO,sBAAsB,EAAE,sBAAsB,CAAC;QACnE,SAAS,CAAC,EAAE,OAAO,sBAAsB,EAAE,kBAAkB,CAAC;QAC9D,WAAW,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;KAClC,CAAC;CACF;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,yBAAyB,GAAG,cAAc,EAAE,CAsbpF;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,EAAE,CAE/C"}