Adds offline XAITTSProvider.test.ts covering voice/format selection,
request shape, error paths, and cost reporting. Spies on global fetch
(the provider's egress point) against a real PuterServer + live
MeteringService.
Closes#2998
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds offline ElevenLabsTTSProvider.test.ts covering voice/format
selection, request shape, error paths, and cost reporting. Spies on
global fetch (the provider's egress point) against a real PuterServer
+ live MeteringService. The companion integration test stays untouched.
Closes#2999
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds offline OpenAITTSProvider.test.ts covering voice/format selection,
request shape, error paths, and cost reporting. Mocks the OpenAI SDK at
the module boundary against a real PuterServer + live MeteringService.
The companion integration test stays untouched.
Closes#3000
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds offline TogetherVideoProvider.test.ts covering parameter mapping
(togetherai: prefix stripping, seconds default vs no_extra_params,
width/height/fps/steps, reference_images / frame_images filtering),
polling for queued → in_progress → completed jobs (under fake timers),
failure / cancellation / missing-url error paths, and per-video
metering. Mocks together-ai at the module boundary against a real
PuterServer + live MeteringService.
Closes#2994
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds offline OpenAIVideoProvider.test.ts covering parameter mapping
(size and seconds snapping to allowed values, input_reference
forwarding), polling for queued/in_progress jobs (under fake timers),
sora-2-pro size tiers (xl/xxl per-second pricing), per-second metering
on default tier, failure handling, and error paths. Mocks the OpenAI
SDK at the module boundary against a real PuterServer + live
MeteringService.
Closes#2993
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds offline GeminiTTSProvider.test.ts covering voice/format selection,
request shape (transcript framing + speechConfig), error paths, and
cost reporting (token-priced input + output:audio batching, including
the PCM-to-WAV wrapping path). Mocks @google/genai at the module
boundary against a real PuterServer + live MeteringService.
Closes#2997
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds offline TTSDriver.test.ts covering provider selection/dispatch
(args.provider, legacy driverAlias via Context.driverName, registered
fallback), voice/format param validation, error mapping, and metering
propagation (provider failures must not bill). Mocks each provider's
SDK / fetch boundary against a real PuterServer wired with credentials
for every TTS provider.
Closes#2995
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds offline AWSPollyTTSProvider.test.ts covering voice/format
selection (caller-supplied, language-derived, default-per-engine
fallback), SSML handling (TextType=ssml routing), request shape to the
AWS SDK SynthesizeSpeechCommand, engine validation, error paths, and
cost reporting. Mocks @aws-sdk/client-polly at the module boundary
against a real PuterServer + live MeteringService.
Closes#2996
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds offline VideoGenerationDriver.test.ts covering provider
selection/dispatch (args.provider, model-id resolution across the
unified catalog, Context.driverName fallback), parameter validation
(seconds + dimension snapping to model.durationSeconds /
model.dimensions, string coercion), error mapping (provider
HttpErrors pass through, SDK errors don't bill), and metering
propagation (driver-level dispatch reaches the provider's
incrementUsage). Mocks each provider's SDK boundary against a real
PuterServer wired with credentials for every video provider.
Closes#2991
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Mocks the OpenAI SDK at the module boundary, boots a real PuterServer
for the wired MeteringService, and exercises construction (xAI base
URL, missing-key throw), model catalog (default + verbatim list),
test_mode bypass, prompt validation, the credit gate (402 before SDK),
model resolution (alias and unknown-id fallback), and the success
path covering URL/b64_json branches plus per-image metering with the
expected microcent override.
closes#2988
Mocks the OpenAI SDK at the module boundary, boots a real PuterServer
for the wired MeteringService, and covers the three model families
the provider treats differently. Exercises construction, model catalog
(dall-e-2 default + verbatim list), test_mode bypass, prompt
validation, the credit gate (402 before SDK), DALL-E request shape
(allowedRatio snap, hd-only-on-DALL-E-3, per-size metering, url and
b64_json output), gpt-image-* token-priced metering (input + output
batched line items at the model rates), and the gpt-image-2 size
normalizer (pixel-budget snap to multiples of 16, 3:1 ratio clamp,
3840 edge cap).
closes#2990
Mocks the together-ai SDK at the module boundary, boots a real
PuterServer for the wired MeteringService, and exercises construction
(missing-key throw), model catalog (default + verbatim list), test_mode
bypass, prompt validation, the credit gate (402 before SDK), all three
pricing branches (per-MP × ratio, per-image, per-tier with resolution
map rewrite), request shape (togetherai: prefix stripping, dimension
snap to multiples of 8 with min 64, optional knob clamping/forwarding,
input_image → image_base64 aliasing), and output handling for both
url/b64_json branches plus the wrapped error message.
closes#2987
Mocks @google/genai at the module boundary, boots a real PuterServer
for the wired MeteringService, and covers both the generateContent
(Flash) and generateImages (Imagen) code paths. Exercises
construction (missing-key throw), model catalog (default + verbatim
list), test_mode bypass, prompt validation, the credit gate (402
before SDK), Flash request shape (aspect ratio, allowedRatio fallback,
inlineData → base64 data URL extraction), Flash 3-line metering
(input + output:text + output:image with the IMAGE-modality token
count), Imagen routing (generateImages, per-image metering,
empty-response and rai-filtered failure modes).
closes#2989
Boots a real PuterServer with API keys for every image provider
configured (so the driver indexes them all), drives
server.drivers.aiImage directly, and mocks each provider SDK at the
module boundary so the driver's routing is exercised without real
network egress. Covers 401 without actor, 400 on unknown model,
catalog dedup + sort, list() and getReportedCosts shape, provider
routing (id-based, lowercased lookups, args.provider override,
Context.driverName fallback), ratio normalization (width/height and
aspect_ratio "w:h" forms), and the ai.log.image audit event firing
both before the upstream call and even when it fails.
closes#2984
Boots a real PuterServer for the wired MeteringService, stubs global
fetch (the provider talks to the Cloudflare REST API directly with no
SDK). Covers construction, model catalog, test_mode bypass, prompt
validation, the credit gate (402 before fetch), request shape (JSON
body, account-scoped /ai/run/<model> endpoint, apiBaseUrl override,
multipart routing for requiresMultipart models, steps clamping
[1,50]), output extraction (binary image/* → base64 data URL, JSON
envelope image with output_format → MIME, http(s) URL passthrough,
success:false 400, non-2xx 400, missing image 400), and per-scheme
cost components (tile-plus-step and flux2-klein-9b-mp split).
closes#2985
Mocks the groq-sdk at the module boundary, boots a real PuterServer
for the wired MeteringService, and exercises construction, model
catalog/resolution, request shape (max_completion_tokens rename, tools
passthrough, content blanking when paired with tool_calls), non-stream
+ streaming output (including Groq's x_groq.usage envelope deviation),
error mapping, and moderation.
closes#2977
Mocks @anthropic-ai/sdk at the module boundary, boots a real
PuterServer for the wired MeteringService/stores/FSService, and
exercises construction (long timeout for Opus 4.7 thinking), model
catalog/resolution, request shape (tool_choice locking, system message
extraction, OpenAI-shape tool_calls → Claude tool_use blocks, tool
role → user tool_result, opus-4.7 temperature drop, adaptive thinking
config, enabled budget thinking + temperature=1 for older Sonnet),
non-stream output (input/output/cache token metering), streaming via
the message_start/content_block_*/message_delta/message_stop event
graph for both text_delta and input_json_delta tool_use, and the
moderation throw.
closes#2958
Mocks the OpenAI SDK at the module boundary, boots a real PuterServer
for the wired MeteringService/stores/FSService, and exercises
construction, model catalog (responses_api_only filtering), argument
validation (messages-array gate, web_search routing — error when no
sibling, delegation when one is set), request shape (max_completion_
tokens rename, gpt-5 vs non-gpt-5 reasoning_effort/verbosity gating,
stream_options gating), non-stream + streaming output (cached-token
splitting), the moderations.create flagging branch (above and at the
0.8 threshold), and error mapping.
closes#2959
Boots a real PuterServer with an ElevenLabs apiKey configured, drives
server.drivers.aiSpeech2Speech, and stubs global fetch (the real
network egress for ElevenLabs). Covers getReportedCosts mirroring
costs.ts, argument validation (test_mode bypass, missing actor 401,
missing audio 400), the credit gate (402 before fetch), the success
path (POST URL with voice id, default + override voice/model, optional
knobs forwarded via FormData and search params, audio stream return
shape), per-second metering math, and error mapping when ElevenLabs
returns a non-2xx body.
closes#2963
Mocks the OpenAI SDK at the module boundary, boots a real PuterServer
for the wired MeteringService, and exercises construction, model
catalog/resolution, request shape (max_tokens, tools, stream_options,
DeepSeek's content-blanking and tool-result system-message workarounds),
non-stream + streaming output paths, error mapping, and moderation.
closes#2976
Mocks the together-ai SDK at the module boundary, boots a real
PuterServer for the wired MeteringService, and clears the kv-cached
model list between tests. Covers construction, model catalog (kv
caching, embedding-type filtering, alias flattening, synthetic
model-fallback-test-1), request shape (togetherai: prefix stripping,
max_tokens omission, tools/stream_options gating), model resolution,
non-stream + streaming output (with input/output cost-key remap),
error mapping, and moderation.
closes#2981
Mocks both the OpenAI SDK and axios at the module boundary, boots a
real PuterServer for the wired MeteringService, and clears the
kv-cached model list between tests. Covers construction (default and
custom apiBaseUrl), model catalog (axios fetch + kv caching, openrouter:
prefix on ids, openrouter/auto filtering), the openrouter/auto disallow
gate, request shape (prefix stripping, usage:{include:true}, stream
options, retry-without-max_tokens on context-length errors, rethrow on
unrelated errors), both cost-calculator branches (cost-bearing vs
per-token fallback) for non-stream and streaming, and moderation.
closes#2980
Mocks the OpenAI SDK at the module boundary (Gemini speaks the
OpenAI-compat dialect at the v1beta/openai endpoint), boots a real
PuterServer for the wired MeteringService, and exercises construction,
model catalog/resolution, request shape (max_completion_tokens rename,
cache_control stripping, stream_options gating), non-stream + streaming
output (cached-token splitting in the metered usage shape), error
mapping, and moderation.
closes#2961
Drops the local makeMeteringStub in favour of a live PuterServer-wired
MeteringService. The OpenAI SDK is still mocked at the module boundary
(the real network egress point); the mock now also exposes a default
export so the test server can boot every chat provider (some import
the default and read .OpenAI off it). Aligns with AGENTS.md: "Prefer
test server over mocking deps."
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* tests: add tests for OCRDriver: [#2964]
Adds offline OCRDriver.test.ts covering both providers:
• test_mode short-circuit; argument validation (missing actor, missing
source, unknown provider, AWS/Mistral not configured)
• aws-textract: raw-bytes vs S3Object source selection (regional
client when fsEntry has a bucket), block normalisation (PAGE/WORD/
TABLE filtered, LINE/LAYOUT_TITLE → text/textract:* blocks),
402 on insufficient credits, per-page metering
• mistral: image vs PDF chunk packaging (image_url with base64 data
URL vs document_url with documentName), pass-through of pages /
annotation / image-limit options, markdown → LINE-block
normalisation with page indices, per-page metering, additional
annotations metering when bbox/document annotation formats are set
• default-provider selection (AWS preferred → Mistral fallback →
500 when neither is configured)
• getReportedCosts mirrors costs.ts
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* tests: OCRDriver uses setupTestServer + real fs/metering
Drops the manual config/clients/stores/services stub apparatus and
the loadFileInput mock in favour of the live wired driver from
server.drivers.aiOcr. The Textract and Mistral SDKs are still mocked
at the module boundary (the real network egress points); inputs go
through the real loadFileInput against real fs/store wiring (data
URLs for most cases; FSService.write produces a real fsEntry for the
PDF documentName test). Aligns with AGENTS.md: "Prefer test server
over mocking deps."
The S3Object-source/regional-client assertion was dropped because it
isn't deterministic against the in-memory S3 store and the driver's
per-region TextractClient cache leaks across tests. That branch is
better exercised by a real-cloud integration test.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* tests: add unit tests for MoonshotProvider with mocked client: [#2979]
Adds offline MoonshotProvider.test.ts covering construction, model
resolution and aliasing, request shape (hardcoded max_tokens=1000,
stream_options gating, tool_use → tool_calls hoisting), vision-model
image-inlining hook, non-stream and streaming output, error logging
and rethrow, and metering. Existing integration test is left
untouched.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* tests: MoonshotProvider uses setupTestServer + real metering
Drops the local makeMeteringStub in favour of a live PuterServer-wired
MeteringService. The OpenAI SDK is still mocked at the module boundary
(the real network egress point); inlineHttpImageUrls is mocked because
verifying the provider invokes it for vision-capable models is the
unit's concern. Aligns with AGENTS.md: "Prefer test server over
mocking deps."
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* tests: add unit tests for MistralAiProvider with mocked client: [#2978]
Adds offline MistralAiProvider.test.ts covering construction, model
resolution and aliasing, request shape (camelCase maxTokens, tool_calls
→ toolCalls and tool_call_id → toolCallId rewrite, complete-vs-stream
routing), non-stream output with the camelCase usage coercion,
streaming with the chunk.data unwrap and toolCalls deviation, error
mapping, and metering. Existing integration test is left untouched.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* tests: MistralAiProvider uses setupTestServer + real metering
Drops the local makeMeteringStub in favour of a live PuterServer-wired
MeteringService. The Mistral SDK is still mocked at the module
boundary (the real network egress point); everything else runs through
the real wired graph. Aligns with AGENTS.md: "Prefer test server over
mocking deps."
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>