@spinabot/brigade 1.9.0 → 1.11.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 +12 -10
- 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/update.d.ts +48 -11
- package/dist/cli/commands/update.d.ts.map +1 -1
- package/dist/cli/commands/update.js +133 -46
- package/dist/cli/commands/update.js.map +1 -1
- package/dist/cli/program/build-program.d.ts.map +1 -1
- package/dist/cli/program/build-program.js +11 -5
- package/dist/cli/program/build-program.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/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 +9 -1
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared types for the direct-provider media-understanding subsystem.
|
|
3
|
+
*
|
|
4
|
+
* ─────────────────────────────────────────────────────────────────────────
|
|
5
|
+
* WHY THIS SUBSYSTEM EXISTS (read before changing)
|
|
6
|
+
* ─────────────────────────────────────────────────────────────────────────
|
|
7
|
+
* Pi's SDK carries only TEXT + IMAGE content between a tool and the model —
|
|
8
|
+
* there is no video or document content block, and Brigade has no aux-model
|
|
9
|
+
* completion helper. So `analyze_media` cannot hand a video or a native /
|
|
10
|
+
* scanned PDF to the CURRENT turn's model: those modalities never reach the
|
|
11
|
+
* provider through the tool-result channel.
|
|
12
|
+
*
|
|
13
|
+
* This subsystem closes that gap by calling provider REST APIs DIRECTLY with
|
|
14
|
+
* the media bytes + a prompt and returning TEXT the tool can put in front of
|
|
15
|
+
* the current model. It is the same shape the reference codebase's
|
|
16
|
+
* media-understanding providers use: a provider adapter takes bytes + a
|
|
17
|
+
* prompt and returns a textual description. Nothing here touches Pi's content
|
|
18
|
+
* model — the output is always a string.
|
|
19
|
+
*
|
|
20
|
+
* Two adapters ship today:
|
|
21
|
+
* • Gemini (Google) — VIDEO via the Files API (upload → poll ACTIVE →
|
|
22
|
+
* generateContent with a fileData part), plus image / PDF inline.
|
|
23
|
+
* • Anthropic — native + scanned PDF via a `document` content block (the
|
|
24
|
+
* provider OCRs internally), plus image blocks.
|
|
25
|
+
*
|
|
26
|
+
* Every HTTP call takes an injectable `fetchImpl` so the whole subsystem is
|
|
27
|
+
* testable with zero real network. Keys are resolved through Brigade's
|
|
28
|
+
* existing credential store (`readBrigadeCredentials`), never invented here.
|
|
29
|
+
*/
|
|
30
|
+
/** The media kinds this subsystem can drive against a provider. */
|
|
31
|
+
export type MediaUnderstandingKind = "image" | "pdf" | "video" | "audio";
|
|
32
|
+
/**
|
|
33
|
+
* Provider ids this subsystem can route to.
|
|
34
|
+
* • `google` / `anthropic` — the bespoke REST adapters (Gemini Files API for
|
|
35
|
+
* VIDEO, Anthropic `document` block for native PDF, plus inline image).
|
|
36
|
+
* • `pi` — a VIRTUAL provider that routes a one-shot image (or audio)
|
|
37
|
+
* understanding call through the Pi SDK (`completeSimple`) against ANY
|
|
38
|
+
* resolved model+provider that declares image (or audio) input. This is
|
|
39
|
+
* what lets an operator with ONLY an OpenAI / Groq / Mistral / OpenRouter /
|
|
40
|
+
* Ollama key understand images — the bespoke REST adapters only know
|
|
41
|
+
* google + anthropic.
|
|
42
|
+
*/
|
|
43
|
+
export type MediaUnderstandingProviderId = "google" | "anthropic" | "pi";
|
|
44
|
+
/**
|
|
45
|
+
* A resolved, image-capable model the Pi path can drive. Mirrors the load-
|
|
46
|
+
* bearing subset of Pi's `Model` (the agent loop hands a full Pi Model here via
|
|
47
|
+
* `cfg.resolveModel`). `input` is Pi's `("text"|"image")[]` — only a model whose
|
|
48
|
+
* `input` includes `"image"` is eligible for image understanding.
|
|
49
|
+
*/
|
|
50
|
+
export interface MediaUnderstandingModel {
|
|
51
|
+
/** Underlying Brigade/Pi provider id (e.g. "openai", "openrouter", "groq"). */
|
|
52
|
+
provider: string;
|
|
53
|
+
/** Model id (e.g. "gpt-4o", "anthropic/claude-sonnet-4-5"). */
|
|
54
|
+
id: string;
|
|
55
|
+
/** Pi input modalities — image understanding requires this to include "image". */
|
|
56
|
+
input?: string[];
|
|
57
|
+
/** Carry the remaining Pi Model fields (api/baseUrl/cost/…) opaquely. */
|
|
58
|
+
[key: string]: unknown;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* One-shot completion seam for the Pi path. The default implementation calls
|
|
62
|
+
* `completeSimple` from `@earendil-works/pi-ai`; tests inject a stub so no real
|
|
63
|
+
* model call happens. Returns the concatenated assistant text.
|
|
64
|
+
*/
|
|
65
|
+
export type PiCompleteFn = (req: PiCompleteRequest) => Promise<string>;
|
|
66
|
+
/** Request shape for {@link PiCompleteFn}. */
|
|
67
|
+
export interface PiCompleteRequest {
|
|
68
|
+
model: MediaUnderstandingModel;
|
|
69
|
+
/** Raw media bytes (image/audio). */
|
|
70
|
+
bytes: Buffer;
|
|
71
|
+
/** Declared MIME (e.g. "image/png", "audio/ogg"). */
|
|
72
|
+
mimeType: string;
|
|
73
|
+
/** Instruction / question for the model. */
|
|
74
|
+
prompt: string;
|
|
75
|
+
/** Resolved API key for the model's provider (may be empty for keyless local providers). */
|
|
76
|
+
apiKey: string;
|
|
77
|
+
signal?: AbortSignal;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* A request to understand one piece of media. `bytes` are the raw file bytes
|
|
81
|
+
* (already acquired + guarded by the caller); `mimeType` is the declared MIME
|
|
82
|
+
* (e.g. `video/mp4`, `application/pdf`, `image/png`). `prompt` is the question
|
|
83
|
+
* / instruction handed to the provider model alongside the media.
|
|
84
|
+
*/
|
|
85
|
+
export interface RunMediaUnderstandingRequest {
|
|
86
|
+
kind: MediaUnderstandingKind;
|
|
87
|
+
bytes: Buffer;
|
|
88
|
+
mimeType: string;
|
|
89
|
+
/** Question / instruction for the provider model. Falls back to a per-kind default. */
|
|
90
|
+
prompt?: string;
|
|
91
|
+
/** Force a specific provider (else `resolveMediaUnderstandingProvider` picks). */
|
|
92
|
+
provider?: MediaUnderstandingProviderId;
|
|
93
|
+
/** Override the provider model id (else the per-kind default for the provider). */
|
|
94
|
+
model?: string;
|
|
95
|
+
/**
|
|
96
|
+
* Max output tokens for the provider answer (Anthropic `max_tokens` / Gemini
|
|
97
|
+
* `maxOutputTokens`). Omitted → the adapter's bounded default. Clamped by the
|
|
98
|
+
* adapter to a sane ceiling.
|
|
99
|
+
*/
|
|
100
|
+
maxTokens?: number;
|
|
101
|
+
/** Resolved credential config — how the subsystem gets provider API keys. */
|
|
102
|
+
cfg: MediaUnderstandingConfig;
|
|
103
|
+
/** Test seam: replaces the global fetch for ALL provider HTTP. */
|
|
104
|
+
fetchImpl?: typeof fetch;
|
|
105
|
+
/** Caller's cancel signal (combined with each request's own timeout). */
|
|
106
|
+
signal?: AbortSignal;
|
|
107
|
+
/**
|
|
108
|
+
* Max RETRIES per provider on a transient failure (HTTP 429 / 5xx / transport
|
|
109
|
+
* error). Default 1 (so up to 2 attempts per provider). 0 disables retry.
|
|
110
|
+
*/
|
|
111
|
+
maxRetries?: number;
|
|
112
|
+
/**
|
|
113
|
+
* Test seam: replaces the inter-retry backoff sleep so tests don't actually
|
|
114
|
+
* wait. Receives the planned delay in ms.
|
|
115
|
+
*/
|
|
116
|
+
sleepFn?: (ms: number) => Promise<void>;
|
|
117
|
+
}
|
|
118
|
+
/** The text result of a media-understanding call, plus what produced it. */
|
|
119
|
+
export interface RunMediaUnderstandingResult {
|
|
120
|
+
text: string;
|
|
121
|
+
provider: MediaUnderstandingProviderId;
|
|
122
|
+
model: string;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Credential + default-model config the subsystem reads. Deliberately small:
|
|
126
|
+
* a `resolveKey(providerId)` closure (so the subsystem never imports the auth
|
|
127
|
+
* store directly — the caller wires Brigade's `readBrigadeCredentials`) plus
|
|
128
|
+
* optional per-kind model/provider defaults from `cfg.tools.mediaUnderstanding`.
|
|
129
|
+
*/
|
|
130
|
+
export interface MediaUnderstandingConfig {
|
|
131
|
+
/**
|
|
132
|
+
* Resolve a provider's API key by Brigade catalog id. Accepts the bespoke
|
|
133
|
+
* ids (`"google"`, `"anthropic"`) AND any underlying provider id the Pi path
|
|
134
|
+
* uses (`"openai"`, `"openrouter"`, `"groq"`, …). Returns an empty string
|
|
135
|
+
* when no key is configured (keyless local providers like Ollama also return
|
|
136
|
+
* ""). The subsystem treats only a NON-EMPTY return as "key present" for the
|
|
137
|
+
* REST adapters; the Pi path tolerates "" for keyless local models.
|
|
138
|
+
*/
|
|
139
|
+
resolveKey: (providerId: string) => string;
|
|
140
|
+
/** Optional default model per kind (from config); overrides the built-in default. */
|
|
141
|
+
defaultModels?: Partial<Record<MediaUnderstandingKind, string>>;
|
|
142
|
+
/** Optional preferred provider per kind (from config); overrides the built-in preference order. */
|
|
143
|
+
preferredProvider?: Partial<Record<MediaUnderstandingKind, MediaUnderstandingProviderId>>;
|
|
144
|
+
/**
|
|
145
|
+
* Optional override of the Gemini API base. Must stay on
|
|
146
|
+
* `generativelanguage.googleapis.com` (a test seam / region override only).
|
|
147
|
+
*/
|
|
148
|
+
geminiBaseUrl?: string;
|
|
149
|
+
/** Optional override of the Anthropic API base (test seam only). */
|
|
150
|
+
anthropicBaseUrl?: string;
|
|
151
|
+
/**
|
|
152
|
+
* Pi-path model resolver. Given an underlying provider id (or, when
|
|
153
|
+
* `provider` is omitted, the subsystem's preferred/first keyed provider),
|
|
154
|
+
* return an IMAGE-capable Pi `Model` to drive via `completeSimple` — or
|
|
155
|
+
* `undefined` when this provider has no image-capable model. Wired from the
|
|
156
|
+
* agent loop's `ModelRegistry`; when ABSENT the Pi path is disabled and the
|
|
157
|
+
* subsystem falls back to the bespoke google/anthropic REST adapters
|
|
158
|
+
* (backward-compatible — legacy/test configs without this keep working).
|
|
159
|
+
*
|
|
160
|
+
* `kind` lets a resolver pick an audio-capable model for `kind:"audio"`
|
|
161
|
+
* (today resolvers may ignore it and return the image model).
|
|
162
|
+
*/
|
|
163
|
+
resolveModel?: (provider: string | undefined, kind: MediaUnderstandingKind) => MediaUnderstandingModel | undefined;
|
|
164
|
+
/**
|
|
165
|
+
* Providers that currently have a configured key (Brigade catalog probe),
|
|
166
|
+
* MOST-PREFERRED first. The Pi path picks the first one for which
|
|
167
|
+
* `resolveModel` yields an image-capable model. Empty/absent → the Pi path
|
|
168
|
+
* has no provider to try (it then reports unavailable for non-google/
|
|
169
|
+
* anthropic setups).
|
|
170
|
+
*/
|
|
171
|
+
listKeyedProviders?: () => string[];
|
|
172
|
+
/**
|
|
173
|
+
* One-shot completion implementation for the Pi path. Defaults to a
|
|
174
|
+
* `completeSimple` wrapper; tests inject a stub to avoid real model calls.
|
|
175
|
+
*/
|
|
176
|
+
piComplete?: PiCompleteFn;
|
|
177
|
+
}
|
|
178
|
+
/** Raised when no provider with a resolved key can handle the requested kind. */
|
|
179
|
+
export declare class MediaUnderstandingUnavailableError extends Error {
|
|
180
|
+
readonly kind: MediaUnderstandingKind;
|
|
181
|
+
constructor(kind: MediaUnderstandingKind, message: string);
|
|
182
|
+
}
|
|
183
|
+
/** Raised when a provider HTTP call fails (non-2xx or transport error). */
|
|
184
|
+
export declare class MediaUnderstandingProviderError extends Error {
|
|
185
|
+
readonly provider: MediaUnderstandingProviderId;
|
|
186
|
+
readonly status?: number;
|
|
187
|
+
constructor(provider: MediaUnderstandingProviderId, message: string, status?: number);
|
|
188
|
+
}
|
|
189
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/agents/media-understanding/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared types for the direct-provider media-understanding subsystem.
|
|
3
|
+
*
|
|
4
|
+
* ─────────────────────────────────────────────────────────────────────────
|
|
5
|
+
* WHY THIS SUBSYSTEM EXISTS (read before changing)
|
|
6
|
+
* ─────────────────────────────────────────────────────────────────────────
|
|
7
|
+
* Pi's SDK carries only TEXT + IMAGE content between a tool and the model —
|
|
8
|
+
* there is no video or document content block, and Brigade has no aux-model
|
|
9
|
+
* completion helper. So `analyze_media` cannot hand a video or a native /
|
|
10
|
+
* scanned PDF to the CURRENT turn's model: those modalities never reach the
|
|
11
|
+
* provider through the tool-result channel.
|
|
12
|
+
*
|
|
13
|
+
* This subsystem closes that gap by calling provider REST APIs DIRECTLY with
|
|
14
|
+
* the media bytes + a prompt and returning TEXT the tool can put in front of
|
|
15
|
+
* the current model. It is the same shape the reference codebase's
|
|
16
|
+
* media-understanding providers use: a provider adapter takes bytes + a
|
|
17
|
+
* prompt and returns a textual description. Nothing here touches Pi's content
|
|
18
|
+
* model — the output is always a string.
|
|
19
|
+
*
|
|
20
|
+
* Two adapters ship today:
|
|
21
|
+
* • Gemini (Google) — VIDEO via the Files API (upload → poll ACTIVE →
|
|
22
|
+
* generateContent with a fileData part), plus image / PDF inline.
|
|
23
|
+
* • Anthropic — native + scanned PDF via a `document` content block (the
|
|
24
|
+
* provider OCRs internally), plus image blocks.
|
|
25
|
+
*
|
|
26
|
+
* Every HTTP call takes an injectable `fetchImpl` so the whole subsystem is
|
|
27
|
+
* testable with zero real network. Keys are resolved through Brigade's
|
|
28
|
+
* existing credential store (`readBrigadeCredentials`), never invented here.
|
|
29
|
+
*/
|
|
30
|
+
/** Raised when no provider with a resolved key can handle the requested kind. */
|
|
31
|
+
export class MediaUnderstandingUnavailableError extends Error {
|
|
32
|
+
kind;
|
|
33
|
+
constructor(kind, message) {
|
|
34
|
+
super(message);
|
|
35
|
+
this.name = "MediaUnderstandingUnavailableError";
|
|
36
|
+
this.kind = kind;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
/** Raised when a provider HTTP call fails (non-2xx or transport error). */
|
|
40
|
+
export class MediaUnderstandingProviderError extends Error {
|
|
41
|
+
provider;
|
|
42
|
+
status;
|
|
43
|
+
constructor(provider, message, status) {
|
|
44
|
+
super(message);
|
|
45
|
+
this.name = "MediaUnderstandingProviderError";
|
|
46
|
+
this.provider = provider;
|
|
47
|
+
if (status !== undefined)
|
|
48
|
+
this.status = status;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/agents/media-understanding/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAiKH,iFAAiF;AACjF,MAAM,OAAO,kCAAmC,SAAQ,KAAK;IACnD,IAAI,CAAyB;IACtC,YAAY,IAA4B,EAAE,OAAe;QACxD,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,oCAAoC,CAAC;QACjD,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IAClB,CAAC;CACD;AAED,2EAA2E;AAC3E,MAAM,OAAO,+BAAgC,SAAQ,KAAK;IAChD,QAAQ,CAA+B;IACvC,MAAM,CAAU;IACzB,YAAY,QAAsC,EAAE,OAAe,EAAE,MAAe;QACnF,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,iCAAiC,CAAC;QAC9C,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,MAAM,KAAK,SAAS;YAAE,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IAChD,CAAC;CACD"}
|
|
@@ -160,6 +160,17 @@ export declare function assembleBrigadeToolset(opts: {
|
|
|
160
160
|
a2aPolicy?: import("./tools/sessions/shared.js").AgentToAgentPolicy;
|
|
161
161
|
spawnedKeys?: ReadonlySet<string>;
|
|
162
162
|
};
|
|
163
|
+
/**
|
|
164
|
+
* Resolved turn-model context — provider + modelId of the model driving
|
|
165
|
+
* this turn. Threaded into `analyze_media` so it can decide whether
|
|
166
|
+
* returning an IMAGE block is meaningful for the active model. Optional;
|
|
167
|
+
* omitted on legacy / test call sites.
|
|
168
|
+
*/
|
|
169
|
+
modelContext?: {
|
|
170
|
+
provider?: string;
|
|
171
|
+
modelId?: string;
|
|
172
|
+
imageInput?: boolean;
|
|
173
|
+
};
|
|
163
174
|
}): BrigadeToolset;
|
|
164
175
|
/**
|
|
165
176
|
* Per-call watchdog budget for the spawn tools. The call's own
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-wiring.d.ts","sourceRoot":"","sources":["../../src/agents/session-wiring.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,oCAAoC,CAAC;AAChF,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AAC1E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAM9D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,KAAK,yBAAyB,EAAwB,MAAM,iBAAiB,CAAC;AAIvF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAcvD,MAAM,WAAW,cAAc;IAC9B,iEAAiE;IACjE,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,wEAAwE;IACxE,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,gFAAgF;IAChF,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,kEAAkE;IAClE,WAAW,EAAE,cAAc,EAAE,CAAC;IAC9B,0EAA0E;IAC1E,YAAY,EAAE;QAAE,MAAM,EAAE,OAAO,CAAC;QAAC,SAAS,EAAE,OAAO,CAAA;KAAE,CAAC;CACtD;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,qBAAqB,GAAG,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAWpG;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE;IAC5C,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ;;;;;;OAMG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC;;;;;;OAMG;IACH,eAAe,CAAC,EAAE;QACjB,gBAAgB,EAAE,MAAM,CAAC;QACzB,WAAW,EAAE,MAAM,CAAC;QACpB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,YAAY,CAAC,EAAE,WAAW,CAAC;QAC3B;2DACmD;QACnD,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,aAAa,CAAC,EAAE,MAAM,CAAC;KACvB,CAAC;IACF;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB;;;;;;;;;;OAUG;IACH,UAAU,CAAC,EAAE,qBAAqB,CAAC;IACnC;;;;;;OAMG;IACH,cAAc,CAAC,EAAE,oBAAoB,CAAC;IACtC;;;;;;;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,4BAA4B,EAAE,sBAAsB,CAAC;QACzE,SAAS,CAAC,EAAE,OAAO,4BAA4B,EAAE,kBAAkB,CAAC;QACpE,WAAW,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;KAClC,CAAC;CACF,GAAG,cAAc,
|
|
1
|
+
{"version":3,"file":"session-wiring.d.ts","sourceRoot":"","sources":["../../src/agents/session-wiring.ts"],"names":[],"mappings":"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"}
|
|
@@ -102,6 +102,7 @@ export function assembleBrigadeToolset(opts) {
|
|
|
102
102
|
...(opts.sessionToolAccess !== undefined
|
|
103
103
|
? { sessionToolAccess: opts.sessionToolAccess }
|
|
104
104
|
: {}),
|
|
105
|
+
...(opts.modelContext !== undefined ? { modelContext: opts.modelContext } : {}),
|
|
105
106
|
});
|
|
106
107
|
// Wrap every tool — `wrapOwnerOnlyToolExecution` is a no-op for the owner
|
|
107
108
|
// AND for non-ownerOnly tools, so the cost is one identity-check per tool.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-wiring.js","sourceRoot":"","sources":["../../src/agents/session-wiring.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAKH,OAAO,EAAE,gCAAgC,EAAE,MAAM,sBAAsB,CAAC;AACxE,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAE3D,OAAO,EAAkC,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AACvF,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,EAAE,0BAA0B,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAC;AACzF,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAGzD;;;;;;;;;GASG;AACH,MAAM,kBAAkB,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,CAAU,CAAC;AAepF;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,uBAAuB,CAAC,MAA6B;IACpE,MAAM,QAAQ,GACb,MAAM,CAAC,KAAK,KAAK,SAAS;QACzB,CAAC,CAAC,IAAI,GAAG,CAAS,CAAC,GAAG,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC,CAAC;QACjE,CAAC,CAAC,SAAS,CAAC;IACd,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAS,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACjG,OAAO,CAAC,QAAgB,EAAW,EAAE;QACpC,IAAI,QAAQ,KAAK,SAAS,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC;YAAE,OAAO,KAAK,CAAC;QACpE,IAAI,OAAO,KAAK,SAAS,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC;YAAE,OAAO,KAAK,CAAC;QACjE,OAAO,IAAI,CAAC;IACb,CAAC,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,sBAAsB,CAAC,
|
|
1
|
+
{"version":3,"file":"session-wiring.js","sourceRoot":"","sources":["../../src/agents/session-wiring.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `analyze_media` tool — comprehensive media + document understanding.
|
|
3
|
+
*
|
|
4
|
+
* The model hands this tool a local file PATH or a URL (+ an optional
|
|
5
|
+
* `question`) and the tool RESOLVES the input into content the CURRENT turn's
|
|
6
|
+
* model can reason about against that question. It auto-detects the kind by
|
|
7
|
+
* extension / MIME and dispatches per-format.
|
|
8
|
+
*
|
|
9
|
+
* ─────────────────────────────────────────────────────────────────────────
|
|
10
|
+
* WHY THIS DESIGN (STEP-0 investigation findings — read before changing)
|
|
11
|
+
* ─────────────────────────────────────────────────────────────────────────
|
|
12
|
+
* 1. TOOL-RESULT CONTENT SHAPE. Pi types a tool's `AgentToolResult.content`
|
|
13
|
+
* as `(TextContent | ImageContent)[]` — TEXT or IMAGE only. There is NO
|
|
14
|
+
* `document` / `pdf` / `video` content-block type anywhere in the Pi SDK,
|
|
15
|
+
* and `Model.input` is `("text" | "image")[]` — the whole SDK content model
|
|
16
|
+
* is text + image. `ImageContent` is `{ type:"image"; data:<base64>;
|
|
17
|
+
* mimeType }`. So an IMAGE can flow to the model as a real multimodal block
|
|
18
|
+
* (the same shape `payload-mutators.ts` prunes from history, proving image
|
|
19
|
+
* blocks reach the provider); a PDF/DOCX/PPTX/XLSX/HTML/VIDEO can NOT be
|
|
20
|
+
* returned as a native non-text block. They must become TEXT.
|
|
21
|
+
*
|
|
22
|
+
* 2. DIRECT-PROVIDER UNDERSTANDING (the gap-closer). For modalities Pi can't
|
|
23
|
+
* carry — VIDEO, native/scanned PDF, and images on a text-only current
|
|
24
|
+
* model — the tool calls a provider REST API DIRECTLY via the
|
|
25
|
+
* media-understanding subsystem (`agents/media-understanding/`): it ships
|
|
26
|
+
* the media bytes + the question to Gemini (video → Files API; image/pdf →
|
|
27
|
+
* inline) or Anthropic (pdf → native `document` block with OCR; image →
|
|
28
|
+
* image block) and gets back TEXT, which it returns for the current model.
|
|
29
|
+
* Keys are resolved through Brigade's existing credential store
|
|
30
|
+
* (`readBrigadeCredentials`), never invented here. This bypasses Pi's
|
|
31
|
+
* text+image content cap WITHOUT needing a Pi aux-model runtime.
|
|
32
|
+
*
|
|
33
|
+
* 3. REUSE. HTML → markdown reuses the existing readability/linkedom extractor
|
|
34
|
+
* (`web-fetch-utils.ts`); URL fetches route through the SSRF guard
|
|
35
|
+
* (`guardedFetch`, `infra/net/fetch-guard.ts`) with size + content-type
|
|
36
|
+
* caps; local paths reuse the outbound media-path guard
|
|
37
|
+
* (`security/media-path-guard.ts`) PLUS a workspace/cwd/cache root scoping
|
|
38
|
+
* so secrets/system files outside allowed roots are refused (the same
|
|
39
|
+
* posture the `read`/path-write guards enforce). Untrusted bytes are
|
|
40
|
+
* wrapped in the external-content envelope (`security/external-content.ts`).
|
|
41
|
+
*
|
|
42
|
+
* ─────────────────────────────────────────────────────────────────────────
|
|
43
|
+
* PER-FORMAT BEHAVIOUR
|
|
44
|
+
* ─────────────────────────────────────────────────────────────────────────
|
|
45
|
+
* • image (png/jpg/jpeg/webp/gif/bmp/heic/heif): when the CURRENT model is
|
|
46
|
+
* vision-capable, returned as an IMAGE block so the model sees it (cheap —
|
|
47
|
+
* no extra call). When the current model is text-only, the tool routes the
|
|
48
|
+
* image to a vision-capable provider and returns the resulting TEXT — via
|
|
49
|
+
* the Pi SDK against ANY keyed provider with an image-capable model
|
|
50
|
+
* (OpenAI / OpenRouter / Groq / xAI / Mistral / Ollama / …), or the bespoke
|
|
51
|
+
* google/anthropic REST adapters — so vision works on any model + any
|
|
52
|
+
* configured provider. HEIC/HEIF cannot be transcoded without a native dep,
|
|
53
|
+
* so they are passed through with their declared mime — most providers
|
|
54
|
+
* reject HEIC, so the tool warns. Capped by `maxBytes`.
|
|
55
|
+
* • audio (mp3/wav/m4a/ogg/oga/flac/aac/opus): routed to the media-
|
|
56
|
+
* understanding subsystem (Gemini inline — audio is GEMINI-ONLY because Pi's
|
|
57
|
+
* content model is text + image, so no Pi-drivable provider can ingest an
|
|
58
|
+
* audio block) and the TEXT transcription / summary is returned, so voice
|
|
59
|
+
* notes work. Needs a Google/Gemini key; with none the tool returns a clear
|
|
60
|
+
* "configure a Gemini key" message (NOT a provider 400).
|
|
61
|
+
* • pdf: when an understanding provider key is configured, the PDF is sent
|
|
62
|
+
* NATIVELY (Anthropic `document` block — OCRs scanned pages + reads layout;
|
|
63
|
+
* or Gemini inline) and the provider's TEXT answer is returned, so scanned
|
|
64
|
+
* / no-text-layer PDFs now work. With no key (or `mode:"text"`) it falls
|
|
65
|
+
* back to per-page text extraction (`unpdf`, zero native deps) honoring a
|
|
66
|
+
* `pages` range. `mode:"provider"` forces the provider path.
|
|
67
|
+
* • docx: unzip (`fflate`) → concatenate `word/document.xml` text runs.
|
|
68
|
+
* • pptx: unzip → per-slide text (`ppt/slides/slideN.xml`), slide-numbered,
|
|
69
|
+
* honoring `pages` as a slide range.
|
|
70
|
+
* • xlsx: unzip → `xl/sharedStrings.xml` + each `xl/worksheets/sheetN.xml`
|
|
71
|
+
* → CSV-ish per-sheet text.
|
|
72
|
+
* • html (or a URL returning HTML): readability/linkedom → markdown.
|
|
73
|
+
* • video (mp4/webm/mov/…): always routed to the media-understanding
|
|
74
|
+
* subsystem (Gemini via the Files API: upload → poll ACTIVE →
|
|
75
|
+
* generateContent with a fileData part), and the model's TEXT description
|
|
76
|
+
* is returned. Needs a Google/Gemini key; with none the tool returns a
|
|
77
|
+
* clear "configure a Gemini key" message.
|
|
78
|
+
*
|
|
79
|
+
* The user's `question` is ALWAYS echoed back as a leading text block so the
|
|
80
|
+
* model knows what to do with the resolved content.
|
|
81
|
+
*
|
|
82
|
+
* SECURITY POSTURE: read capability — NOT owner-only — but it MUST honour the
|
|
83
|
+
* path guard (local) + SSRF guard (URL). Registered for every sender; no
|
|
84
|
+
* mutation, no spend.
|
|
85
|
+
*/
|
|
86
|
+
import { Type } from "typebox";
|
|
87
|
+
import { downscaleImageToBudget } from "./image-downscale.js";
|
|
88
|
+
import { readMediaCache, writeMediaCache } from "./media-cache.js";
|
|
89
|
+
import { type MediaUnderstandingConfig, type RunMediaUnderstandingRequest, type RunMediaUnderstandingResult } from "../media-understanding/index.js";
|
|
90
|
+
import type { BrigadeTool } from "./types.js";
|
|
91
|
+
/** Default hard cap on bytes read for ANY source (image bytes, doc bytes, fetched body). */
|
|
92
|
+
declare const DEFAULT_MAX_BYTES: number;
|
|
93
|
+
/** Image blocks are the most token-expensive — cap them tighter by default. */
|
|
94
|
+
declare const DEFAULT_IMAGE_MAX_BYTES: number;
|
|
95
|
+
/** Max characters of extracted text returned to the model (keeps the turn bounded). */
|
|
96
|
+
declare const DEFAULT_MAX_CHARS = 60000;
|
|
97
|
+
export type MediaKind = "image" | "pdf" | "docx" | "pptx" | "xlsx" | "html" | "video" | "audio" | "text" | "odt" | "ods" | "odp" | "epub" | "rtf" | "ipynb";
|
|
98
|
+
/** Pull a lowercase extension (no dot) from a path or URL pathname. */
|
|
99
|
+
export declare function extensionOf(source: string): string;
|
|
100
|
+
/**
|
|
101
|
+
* Resolve the kind. Explicit `kind` override wins; else extension; else MIME
|
|
102
|
+
* (URL responses). Returns undefined when nothing matches (unsupported).
|
|
103
|
+
*/
|
|
104
|
+
export declare function detectKind(args: {
|
|
105
|
+
source: string;
|
|
106
|
+
override?: string;
|
|
107
|
+
mime?: string;
|
|
108
|
+
}): MediaKind | undefined;
|
|
109
|
+
declare const AnalyzeMediaParams: Type.TObject<{
|
|
110
|
+
source: Type.TOptional<Type.TString>;
|
|
111
|
+
sources: Type.TOptional<Type.TArray<Type.TString>>;
|
|
112
|
+
question: Type.TOptional<Type.TString>;
|
|
113
|
+
prompt: Type.TOptional<Type.TString>;
|
|
114
|
+
pages: Type.TOptional<Type.TString>;
|
|
115
|
+
includeImages: Type.TOptional<Type.TBoolean>;
|
|
116
|
+
language: Type.TOptional<Type.TString>;
|
|
117
|
+
provider: Type.TOptional<Type.TUnion<[Type.TLiteral<"google">, Type.TLiteral<"anthropic">]>>;
|
|
118
|
+
model: Type.TOptional<Type.TString>;
|
|
119
|
+
mode: Type.TOptional<Type.TUnion<[Type.TLiteral<"auto">, Type.TLiteral<"provider">, Type.TLiteral<"text">]>>;
|
|
120
|
+
maxBytes: Type.TOptional<Type.TInteger>;
|
|
121
|
+
maxTokens: Type.TOptional<Type.TInteger>;
|
|
122
|
+
kind: Type.TOptional<Type.TUnion<[Type.TLiteral<"image">, Type.TLiteral<"pdf">, Type.TLiteral<"docx">, Type.TLiteral<"pptx">, Type.TLiteral<"xlsx">, Type.TLiteral<"html">, Type.TLiteral<"video">, Type.TLiteral<"audio">, Type.TLiteral<"text">, Type.TLiteral<"odt">, Type.TLiteral<"ods">, Type.TLiteral<"odp">, Type.TLiteral<"epub">, Type.TLiteral<"rtf">, Type.TLiteral<"ipynb">]>>;
|
|
123
|
+
}>;
|
|
124
|
+
export interface AnalyzeMediaDetails {
|
|
125
|
+
ok: boolean;
|
|
126
|
+
source: string;
|
|
127
|
+
sourceType: "url" | "path";
|
|
128
|
+
kind?: MediaKind;
|
|
129
|
+
mimeType?: string;
|
|
130
|
+
bytes?: number;
|
|
131
|
+
/** What block type was returned to the model. */
|
|
132
|
+
returned: "image" | "text" | "none";
|
|
133
|
+
pages?: string;
|
|
134
|
+
truncated?: boolean;
|
|
135
|
+
warning?: string;
|
|
136
|
+
message?: string;
|
|
137
|
+
/** When the result came from a direct provider call: which provider + model produced it. */
|
|
138
|
+
provider?: string;
|
|
139
|
+
providerModel?: string;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Minimal model context the tool uses to decide whether returning an IMAGE
|
|
143
|
+
* block is meaningful. Threaded from the agent loop (provider + modelId of the
|
|
144
|
+
* resolved turn model). All fields optional — when absent the tool assumes the
|
|
145
|
+
* model CAN see images (the common case) but still annotates uncertainty for
|
|
146
|
+
* the operator.
|
|
147
|
+
*/
|
|
148
|
+
export interface AnalyzeMediaModelContext {
|
|
149
|
+
provider?: string;
|
|
150
|
+
modelId?: string;
|
|
151
|
+
/** Explicit override of image capability when the caller already resolved `model.input`. */
|
|
152
|
+
imageInput?: boolean;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Decide whether the current model can consume an IMAGE block. When
|
|
156
|
+
* `imageInput` is set explicitly we trust it. Otherwise we infer from the
|
|
157
|
+
* provider/model id with a conservative, self-contained heuristic (no heavy
|
|
158
|
+
* model-resolution on the hot path): the major multimodal families return
|
|
159
|
+
* true; a small set of known text-only model-id markers return false; unknown
|
|
160
|
+
* → undefined ("assume yes, note it").
|
|
161
|
+
*/
|
|
162
|
+
export declare function modelLikelySeesImages(ctx: AnalyzeMediaModelContext | undefined): boolean | undefined;
|
|
163
|
+
interface AcquiredBytes {
|
|
164
|
+
bytes: Buffer;
|
|
165
|
+
mime?: string;
|
|
166
|
+
truncated: boolean;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Read a LOCAL file with the same safety posture as `read` / outbound media:
|
|
170
|
+
* 1. media-path guard (refuse secrets / system files / credential dirs).
|
|
171
|
+
* 2. allowed-root scoping (must be under workspace / cwd / cache / temp /
|
|
172
|
+
* state media subtree) — refuses arbitrary absolute reads outside roots.
|
|
173
|
+
* Symlinks are resolved first (the guards do this too) so a benign name can't
|
|
174
|
+
* smuggle a denied target.
|
|
175
|
+
*/
|
|
176
|
+
declare function acquireLocalBytes(source: string, opts: {
|
|
177
|
+
workspaceDir?: string;
|
|
178
|
+
cwd?: string;
|
|
179
|
+
maxBytes: number;
|
|
180
|
+
ownerLocalAccess?: boolean;
|
|
181
|
+
}): Promise<AcquiredBytes>;
|
|
182
|
+
/**
|
|
183
|
+
* Fetch a URL through the SSRF guard with size + timeout caps. Reads the body
|
|
184
|
+
* in bounded chunks so a giant response can't blow memory.
|
|
185
|
+
*/
|
|
186
|
+
declare function acquireUrlBytes(source: string, opts: {
|
|
187
|
+
maxBytes: number;
|
|
188
|
+
signal?: AbortSignal;
|
|
189
|
+
}): Promise<AcquiredBytes>;
|
|
190
|
+
/**
|
|
191
|
+
* Parse a 1-indexed page/slide range like "1-5", "3", "2-" into a predicate
|
|
192
|
+
* over 1-indexed page numbers. Invalid input → accept all (best-effort, never
|
|
193
|
+
* throws). Exported for tests.
|
|
194
|
+
*/
|
|
195
|
+
export declare function parsePageRange(spec: string | undefined, total: number): (pageNum1: number) => boolean;
|
|
196
|
+
export interface MakeAnalyzeMediaToolOptions {
|
|
197
|
+
/** Workspace dir — an allowed root for local-path reads. */
|
|
198
|
+
workspaceDir?: string;
|
|
199
|
+
/** Process cwd — an allowed root for local-path reads. */
|
|
200
|
+
cwd?: string;
|
|
201
|
+
/**
|
|
202
|
+
* OWNER local turn (TUI / desktop / the operator's own channel messages):
|
|
203
|
+
* widen the allowed local-read roots to the operator's HOME dir so a
|
|
204
|
+
* user-typed absolute path into Downloads / Desktop / Documents resolves
|
|
205
|
+
* (the common "analyze C:\Users\me\Downloads\report.pdf" case). MUST stay
|
|
206
|
+
* false/undefined for an untrusted remote channel sender so they can't make
|
|
207
|
+
* Brigade read the operator's home. The media-path guard still refuses
|
|
208
|
+
* secrets / system files even when this is on.
|
|
209
|
+
*/
|
|
210
|
+
ownerLocalAccess?: boolean;
|
|
211
|
+
/** Caller's agent id — selects which auth profiles back the provider keys. */
|
|
212
|
+
agentId?: string;
|
|
213
|
+
/** Resolved turn model context — drives whether an IMAGE block is meaningful. */
|
|
214
|
+
modelContext?: AnalyzeMediaModelContext;
|
|
215
|
+
/** Test seam: replace the URL fetch acquisition. */
|
|
216
|
+
acquireUrl?: typeof acquireUrlBytes;
|
|
217
|
+
/** Test seam: replace the local-file acquisition. */
|
|
218
|
+
acquireLocal?: typeof acquireLocalBytes;
|
|
219
|
+
/**
|
|
220
|
+
* Media-understanding config (key resolution + per-kind defaults). Lazily
|
|
221
|
+
* built from Brigade's credential store via `buildMediaUnderstandingConfig`
|
|
222
|
+
* when omitted; tests inject one with a stub `resolveKey`.
|
|
223
|
+
*/
|
|
224
|
+
mediaUnderstandingConfig?: MediaUnderstandingConfig;
|
|
225
|
+
/** Test seam: replace the media-understanding entry point (mocks provider HTTP). */
|
|
226
|
+
runMediaUnderstanding?: (req: RunMediaUnderstandingRequest) => Promise<RunMediaUnderstandingResult>;
|
|
227
|
+
/**
|
|
228
|
+
* Test seam: replace the oversize-image downscaler (defaults to the real
|
|
229
|
+
* jimp-backed `downscaleImageToBudget`). Lets tests assert the resize/branch
|
|
230
|
+
* without bundling a real codec.
|
|
231
|
+
*/
|
|
232
|
+
downscaleImage?: typeof downscaleImageToBudget;
|
|
233
|
+
/**
|
|
234
|
+
* Cache provider (Gemini/Anthropic) understanding RESULTS keyed by
|
|
235
|
+
* `sha256(bytes)+question+provider+model+maxTokens` so re-analyzing the same
|
|
236
|
+
* media doesn't pay for the call twice. Default ON (disk-backed LRU under
|
|
237
|
+
* `resolveCacheDir()`). Set `false` to disable. Tests pass injected
|
|
238
|
+
* `readCache`/`writeCache` to avoid disk I/O.
|
|
239
|
+
*/
|
|
240
|
+
resultCache?: boolean;
|
|
241
|
+
/** Test seam: replace the cache READ (defaults to the disk cache). */
|
|
242
|
+
readCache?: typeof readMediaCache;
|
|
243
|
+
/** Test seam: replace the cache WRITE (defaults to the disk cache). */
|
|
244
|
+
writeCache?: typeof writeMediaCache;
|
|
245
|
+
}
|
|
246
|
+
export declare function makeAnalyzeMediaTool(opts?: MakeAnalyzeMediaToolOptions): BrigadeTool<typeof AnalyzeMediaParams, AnalyzeMediaDetails>;
|
|
247
|
+
/**
|
|
248
|
+
* Build the provider prompt for an AUDIO call, folding in an optional spoken-
|
|
249
|
+
* language hint and the caller's question/context. Gemini's generateContent has
|
|
250
|
+
* no language field, so the hint is expressed in the instruction text. When the
|
|
251
|
+
* caller gives no question, default to transcribe-then-summarize.
|
|
252
|
+
*/
|
|
253
|
+
export declare function buildAudioPrompt(question: string, language?: string): string;
|
|
254
|
+
/**
|
|
255
|
+
* Heuristic: do these bytes look like UTF-8 text (so an unknown extension/MIME
|
|
256
|
+
* can be read as the `text` kind rather than rejected)? Rejects anything with a
|
|
257
|
+
* NUL byte or a high ratio of C0 control bytes (binary), and validates that a
|
|
258
|
+
* leading sample decodes as UTF-8 without replacement characters. Conservative
|
|
259
|
+
* — a false negative just yields the old "unsupported" message.
|
|
260
|
+
*/
|
|
261
|
+
export declare function looksLikeUtf8Text(bytes: Buffer): boolean;
|
|
262
|
+
export { DEFAULT_IMAGE_MAX_BYTES, DEFAULT_MAX_BYTES, DEFAULT_MAX_CHARS };
|
|
263
|
+
//# sourceMappingURL=analyze-media-tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analyze-media-tool.d.ts","sourceRoot":"","sources":["../../../src/agents/tools/analyze-media-tool.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoFG;AAOH,OAAO,EAAE,IAAI,EAAe,MAAM,SAAS,CAAC;AAK5C,OAAO,EACN,sBAAsB,EAGtB,MAAM,sBAAsB,CAAC;AAM9B,OAAO,EAEN,cAAc,EACd,eAAe,EAEf,MAAM,kBAAkB,CAAC;AAO1B,OAAO,EAIN,KAAK,wBAAwB,EAE7B,KAAK,4BAA4B,EACjC,KAAK,2BAA2B,EAChC,MAAM,iCAAiC,CAAC;AASzC,OAAO,KAAK,EAAmB,WAAW,EAAE,MAAM,YAAY,CAAC;AAI/D,4FAA4F;AAC5F,QAAA,MAAM,iBAAiB,QAAmB,CAAC;AAG3C,+EAA+E;AAC/E,QAAA,MAAM,uBAAuB,QAAkB,CAAC;AAChD,uFAAuF;AACvF,QAAA,MAAM,iBAAiB,QAAS,CAAC;AA0CjC,MAAM,MAAM,SAAS,GAClB,OAAO,GACP,KAAK,GACL,MAAM,GACN,MAAM,GACN,MAAM,GACN,MAAM,GACN,OAAO,GACP,OAAO,GACP,MAAM,GAEN,KAAK,GACL,KAAK,GACL,KAAK,GACL,MAAM,GACN,KAAK,GACL,OAAO,CAAC;AA0KX,uEAAuE;AACvE,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CASlD;AAiED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;CACd,GAAG,SAAS,GAAG,SAAS,CA0BxB;AAID,QAAA,MAAM,kBAAkB;;;;;;;;;;;;;;EAqGtB,CAAC;AAEH,MAAM,WAAW,mBAAmB;IACnC,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,KAAK,GAAG,MAAM,CAAC;IAC3B,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iDAAiD;IACjD,QAAQ,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;IACpC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,4FAA4F;IAC5F,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;CACvB;AAID;;;;;;GAMG;AACH,MAAM,WAAW,wBAAwB;IACxC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,4FAA4F;IAC5F,UAAU,CAAC,EAAE,OAAO,CAAC;CACrB;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACpC,GAAG,EAAE,wBAAwB,GAAG,SAAS,GACvC,OAAO,GAAG,SAAS,CAerB;AAID,UAAU,aAAa;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,OAAO,CAAC;CACnB;AAqGD;;;;;;;GAOG;AACH,iBAAe,iBAAiB,CAC/B,MAAM,EAAE,MAAM,EACd,IAAI,EAAE;IAAE,YAAY,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,gBAAgB,CAAC,EAAE,OAAO,CAAA;CAAE,GACzF,OAAO,CAAC,aAAa,CAAC,CA8BxB;AAED;;;GAGG;AACH,iBAAe,eAAe,CAC7B,MAAM,EAAE,MAAM,EACd,IAAI,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,WAAW,CAAA;CAAE,GAC9C,OAAO,CAAC,aAAa,CAAC,CAkBxB;AAwCD;;;;GAIG;AACH,wBAAgB,cAAc,CAC7B,IAAI,EAAE,MAAM,GAAG,SAAS,EACxB,KAAK,EAAE,MAAM,GACX,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAY/B;AAqYD,MAAM,WAAW,2BAA2B;IAC3C,4DAA4D;IAC5D,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,0DAA0D;IAC1D,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;;;;;;OAQG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,8EAA8E;IAC9E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iFAAiF;IACjF,YAAY,CAAC,EAAE,wBAAwB,CAAC;IACxC,oDAAoD;IACpD,UAAU,CAAC,EAAE,OAAO,eAAe,CAAC;IACpC,qDAAqD;IACrD,YAAY,CAAC,EAAE,OAAO,iBAAiB,CAAC;IACxC;;;;OAIG;IACH,wBAAwB,CAAC,EAAE,wBAAwB,CAAC;IACpD,oFAAoF;IACpF,qBAAqB,CAAC,EAAE,CAAC,GAAG,EAAE,4BAA4B,KAAK,OAAO,CAAC,2BAA2B,CAAC,CAAC;IACpG;;;;OAIG;IACH,cAAc,CAAC,EAAE,OAAO,sBAAsB,CAAC;IAC/C;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,sEAAsE;IACtE,SAAS,CAAC,EAAE,OAAO,cAAc,CAAC;IAClC,uEAAuE;IACvE,UAAU,CAAC,EAAE,OAAO,eAAe,CAAC;CACpC;AAED,wBAAgB,oBAAoB,CACnC,IAAI,GAAE,2BAAgC,GACpC,WAAW,CAAC,OAAO,kBAAkB,EAAE,mBAAmB,CAAC,CAquC7D;AAqED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAS5E;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAgBxD;AAiCD,OAAO,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,CAAC"}
|