@nebutra/agents 1.1.1 → 2.0.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/LICENSE +21 -676
- package/README.md +7 -3
- package/dist/{agent-CahnMASx.d.ts → agent-DDGWuUpe.d.ts} +1 -1
- package/dist/{chunk-B7XWL35G.js → chunk-7VL333VJ.js} +5 -1
- package/dist/{chunk-5LX742GP.js → chunk-C4CC5UEF.js} +25 -53
- package/{src/env.ts → dist/chunk-FCXWOXII.js} +23 -47
- package/dist/chunk-HVLFZW6E.js +71 -0
- package/dist/chunk-HZQXXUKB.js +171 -0
- package/dist/{chunk-RLWM437Q.js → chunk-KC6SOI5Z.js} +19 -4
- package/dist/{chunk-NPQECBXL.js → chunk-S5N743EP.js} +60 -7
- package/dist/chunk-VZPQOXWW.js +47 -0
- package/dist/{chunk-NVPE5EDI.js → chunk-YBCIJKC7.js} +20 -3
- package/dist/env.d.ts +45 -0
- package/dist/env.js +12 -0
- package/dist/fallback.d.ts +100 -0
- package/dist/fallback.js +18 -0
- package/dist/generation/index.d.ts +122 -0
- package/dist/generation/index.js +19 -0
- package/dist/index.d.ts +22 -329
- package/dist/index.js +59 -245
- package/dist/observability.d.ts +46 -0
- package/dist/observability.js +13 -0
- package/dist/providers/langchain.d.ts +2 -2
- package/dist/providers/vercel-ai.d.ts +2 -2
- package/dist/providers/vercel-ai.js +15 -7
- package/dist/sdk/config.d.ts +6 -0
- package/dist/sdk/config.js +2 -1
- package/dist/sdk/index.d.ts +37 -4
- package/dist/sdk/index.js +23 -8
- package/dist/sdk/models.d.ts +20 -27
- package/dist/sdk/models.js +5 -3
- package/dist/sdk/provider.d.ts +1 -0
- package/dist/sdk/provider.js +3 -3
- package/dist/tools.d.ts +1 -1
- package/dist/{types-NtgB3pch.d.ts → types-BytC-HfQ.d.ts} +1 -5
- package/package.json +73 -19
- package/.turbo/turbo-build.log +0 -40
- package/.turbo/turbo-test.log +0 -19
- package/.turbo/turbo-typecheck.log +0 -4
- package/AGENTS.md +0 -63
- package/CHANGELOG.md +0 -36
- package/dist/chunk-5JZJ5KMC.js +0 -37
- package/src/__tests__/cost-observability.test.ts +0 -172
- package/src/__tests__/fallback-wiring.test.ts +0 -313
- package/src/__tests__/generation.test.ts +0 -111
- package/src/__tests__/public-api.test.ts +0 -114
- package/src/__tests__/runtime-gateway.test.ts +0 -108
- package/src/agent.ts +0 -117
- package/src/context.ts +0 -99
- package/src/fallback.ts +0 -358
- package/src/gateway.ts +0 -234
- package/src/generation/index.ts +0 -157
- package/src/generation/mock-provider.ts +0 -123
- package/src/generation/types.ts +0 -87
- package/src/index.ts +0 -104
- package/src/memory.ts +0 -126
- package/src/observability.ts +0 -102
- package/src/orchestrator.ts +0 -147
- package/src/providers/langchain.ts +0 -28
- package/src/providers/vercel-ai.ts +0 -114
- package/src/router.ts +0 -158
- package/src/sdk/config.ts +0 -73
- package/src/sdk/index.ts +0 -214
- package/src/sdk/models.ts +0 -57
- package/src/sdk/provider.ts +0 -80
- package/src/tenant.ts +0 -52
- package/src/tools.ts +0 -65
- package/src/types.ts +0 -114
- package/tsconfig.json +0 -12
- package/tsup.config.ts +0 -21
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
// src/sdk/payload-guard.ts
|
|
2
|
+
var OPENAI_MAX_PROPERTY_NAME_LENGTH = 256;
|
|
3
|
+
function isObjectLike(value) {
|
|
4
|
+
return typeof value === "object" && value !== null;
|
|
5
|
+
}
|
|
6
|
+
function pathSegment(key) {
|
|
7
|
+
const preview = key.length > 32 ? `${key.slice(0, 29)}...` : key;
|
|
8
|
+
return /^[A-Za-z_$][\w$]*$/.test(preview) ? `.${preview}` : `[${JSON.stringify(preview)}]`;
|
|
9
|
+
}
|
|
10
|
+
function findOversizedPropertyName(value, maxLength = OPENAI_MAX_PROPERTY_NAME_LENGTH) {
|
|
11
|
+
const seen = /* @__PURE__ */ new WeakSet();
|
|
12
|
+
function visit(candidate, path) {
|
|
13
|
+
if (!isObjectLike(candidate)) return null;
|
|
14
|
+
if (seen.has(candidate)) return null;
|
|
15
|
+
seen.add(candidate);
|
|
16
|
+
if (Array.isArray(candidate)) {
|
|
17
|
+
for (let index = 0; index < candidate.length; index += 1) {
|
|
18
|
+
const issue = visit(candidate[index], `${path}[${index}]`);
|
|
19
|
+
if (issue) return issue;
|
|
20
|
+
}
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
for (const [key, nested] of Object.entries(candidate)) {
|
|
24
|
+
const nestedPath = `${path}${pathSegment(key)}`;
|
|
25
|
+
if (key.length > maxLength) {
|
|
26
|
+
return { path: nestedPath, length: key.length };
|
|
27
|
+
}
|
|
28
|
+
const issue = visit(nested, nestedPath);
|
|
29
|
+
if (issue) return issue;
|
|
30
|
+
}
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
return visit(value, "$");
|
|
34
|
+
}
|
|
35
|
+
function assertSafeOpenAIJsonPayload(label, value) {
|
|
36
|
+
const issue = findOversizedPropertyName(value);
|
|
37
|
+
if (!issue) return;
|
|
38
|
+
throw new Error(
|
|
39
|
+
`${label} contains an object property name at ${issue.path} that is ${issue.length} characters long; maximum is ${OPENAI_MAX_PROPERTY_NAME_LENGTH}. Put generated text in a string value instead of using it as a JSON key.`
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export {
|
|
44
|
+
OPENAI_MAX_PROPERTY_NAME_LENGTH,
|
|
45
|
+
findOversizedPropertyName,
|
|
46
|
+
assertSafeOpenAIJsonPayload
|
|
47
|
+
};
|
|
@@ -1,13 +1,28 @@
|
|
|
1
|
+
import {
|
|
2
|
+
models
|
|
3
|
+
} from "./chunk-HVLFZW6E.js";
|
|
4
|
+
|
|
1
5
|
// src/sdk/config.ts
|
|
2
6
|
import { z } from "zod";
|
|
3
|
-
var ProviderType = z.enum([
|
|
7
|
+
var ProviderType = z.enum([
|
|
8
|
+
"openrouter",
|
|
9
|
+
"openai",
|
|
10
|
+
"siliconflow",
|
|
11
|
+
"sensenova",
|
|
12
|
+
"ai302",
|
|
13
|
+
"gateway"
|
|
14
|
+
]);
|
|
4
15
|
var NebutraAIConfigSchema = z.object({
|
|
5
16
|
/** Which provider backend to use. Defaults to "openrouter". */
|
|
6
17
|
provider: ProviderType.default("openrouter"),
|
|
7
18
|
/** API key override. Falls back to env vars per provider. */
|
|
8
19
|
apiKey: z.string().optional(),
|
|
9
|
-
/**
|
|
10
|
-
|
|
20
|
+
/**
|
|
21
|
+
* Default model id. Reads the generated frontier flagship rather than naming
|
|
22
|
+
* a version, so `pnpm gen:frontier-models` moves it and it cannot go stale
|
|
23
|
+
* here independently of everywhere else.
|
|
24
|
+
*/
|
|
25
|
+
defaultModel: z.string().default(models.flagship),
|
|
11
26
|
/** Default temperature for generations. */
|
|
12
27
|
temperature: z.number().min(0).max(2).default(0.7),
|
|
13
28
|
/** Default max tokens for output. */
|
|
@@ -23,6 +38,8 @@ function resolveApiKey(config) {
|
|
|
23
38
|
openrouter: "OPENROUTER_API_KEY",
|
|
24
39
|
openai: "OPENAI_API_KEY",
|
|
25
40
|
siliconflow: "SILICONFLOW_API_KEY",
|
|
41
|
+
sensenova: "SENSENOVA_API_KEY",
|
|
42
|
+
ai302: "AI302_API_KEY",
|
|
26
43
|
gateway: "VERCEL_OIDC_TOKEN"
|
|
27
44
|
};
|
|
28
45
|
const envVar = envMap[config.provider];
|
package/dist/env.d.ts
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Environment validation for `@nebutra/agents`.
|
|
5
|
+
*
|
|
6
|
+
* All variables are OPTIONAL — the package must work with zero new env config.
|
|
7
|
+
* Provider keys (OPENROUTER_API_KEY, OPENAI_API_KEY, ANTHROPIC_API_KEY, etc.)
|
|
8
|
+
* are validated lazily by the provider resolver, not here.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/** Comma-separated provider chain. Order = priority. */
|
|
12
|
+
declare const FallbackProviderName: z.ZodEnum<{
|
|
13
|
+
openrouter: "openrouter";
|
|
14
|
+
anthropic: "anthropic";
|
|
15
|
+
openai: "openai";
|
|
16
|
+
ai302: "ai302";
|
|
17
|
+
}>;
|
|
18
|
+
type FallbackProviderName = z.infer<typeof FallbackProviderName>;
|
|
19
|
+
declare const AgentsEnvSchema: z.ZodObject<{
|
|
20
|
+
ANTHROPIC_API_KEY: z.ZodOptional<z.ZodString>;
|
|
21
|
+
LANGFUSE_PUBLIC_KEY: z.ZodOptional<z.ZodString>;
|
|
22
|
+
LANGFUSE_SECRET_KEY: z.ZodOptional<z.ZodString>;
|
|
23
|
+
LANGFUSE_HOST: z.ZodDefault<z.ZodString>;
|
|
24
|
+
LLM_FALLBACK_CHAIN: z.ZodDefault<z.ZodPipe<z.ZodPipe<z.ZodString, z.ZodTransform<string[], string>>, z.ZodArray<z.ZodEnum<{
|
|
25
|
+
openrouter: "openrouter";
|
|
26
|
+
anthropic: "anthropic";
|
|
27
|
+
openai: "openai";
|
|
28
|
+
ai302: "ai302";
|
|
29
|
+
}>>>>;
|
|
30
|
+
LLM_EMBEDDING_FALLBACK_CHAIN: z.ZodDefault<z.ZodPipe<z.ZodPipe<z.ZodString, z.ZodTransform<string[], string>>, z.ZodArray<z.ZodEnum<{
|
|
31
|
+
openrouter: "openrouter";
|
|
32
|
+
anthropic: "anthropic";
|
|
33
|
+
openai: "openai";
|
|
34
|
+
ai302: "ai302";
|
|
35
|
+
}>>>>;
|
|
36
|
+
}, z.core.$strip>;
|
|
37
|
+
type AgentsEnv = z.infer<typeof AgentsEnvSchema>;
|
|
38
|
+
/** Returns the validated env (cached). Safe to call from any runtime. */
|
|
39
|
+
declare function getAgentsEnv(): AgentsEnv;
|
|
40
|
+
/** Test helper — clears cache so updated process.env is picked up. */
|
|
41
|
+
declare function _resetAgentsEnvCache(): void;
|
|
42
|
+
/** True iff Langfuse credentials are present. */
|
|
43
|
+
declare function isLangfuseConfigured(): boolean;
|
|
44
|
+
|
|
45
|
+
export { type AgentsEnv, AgentsEnvSchema, FallbackProviderName, _resetAgentsEnvCache, getAgentsEnv, isLangfuseConfigured };
|
package/dist/env.js
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { EmbeddingModel, LanguageModel } from 'ai';
|
|
2
|
+
export { ModelMessage } from 'ai';
|
|
3
|
+
import { FallbackProviderName } from './env.js';
|
|
4
|
+
import 'zod';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Multi-provider fallback chain + prompt-caching helpers.
|
|
8
|
+
*
|
|
9
|
+
* Cost & reliability primitives for production LLM workloads:
|
|
10
|
+
*
|
|
11
|
+
* 1. `createFallbackModel()` — picks a primary model and returns a callable
|
|
12
|
+
* that retries on retryable errors (429 / 5xx / network) by swapping to
|
|
13
|
+
* the next provider in `LLM_FALLBACK_CHAIN`.
|
|
14
|
+
*
|
|
15
|
+
* 2. `withCacheControl()` — annotates the system message with Anthropic
|
|
16
|
+
* `cacheControl: { type: 'ephemeral' }` for a 90% discount on cached
|
|
17
|
+
* prefix tokens. OpenAI auto-caches when the prefix is stable and ≥1024
|
|
18
|
+
* tokens — see comment in `generateWithFallback()`.
|
|
19
|
+
*
|
|
20
|
+
* Reference: https://sdk.vercel.ai/docs/ai-sdk-providers/anthropic#cache-control
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Filter a chain to providers whose API key is present in env.
|
|
25
|
+
* Returns the original chain unchanged if NO providers have keys (so callers
|
|
26
|
+
* still see a meaningful error rather than an empty-chain throw).
|
|
27
|
+
*/
|
|
28
|
+
declare function filterAvailableProviders(chain: readonly FallbackProviderName[]): readonly FallbackProviderName[];
|
|
29
|
+
declare function isRetryableError(error: unknown): boolean;
|
|
30
|
+
interface FallbackResult<T> {
|
|
31
|
+
result: T;
|
|
32
|
+
provider: FallbackProviderName;
|
|
33
|
+
attempts: number;
|
|
34
|
+
}
|
|
35
|
+
interface CreateFallbackModelOptions {
|
|
36
|
+
/** Override the default chain from env. */
|
|
37
|
+
chain?: readonly FallbackProviderName[];
|
|
38
|
+
/** Model preset / id passed to each provider in the chain. */
|
|
39
|
+
model?: string;
|
|
40
|
+
/**
|
|
41
|
+
* If true (default), filter the chain to providers whose API key is present
|
|
42
|
+
* in env. Set false to keep the original chain (caller wants to surface
|
|
43
|
+
* "missing key" errors as fallback steps — useful for tests).
|
|
44
|
+
*/
|
|
45
|
+
filterAvailable?: boolean;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Run an AI SDK call against the configured fallback chain.
|
|
49
|
+
*
|
|
50
|
+
* The caller provides an `invoke(model)` function — usually a closure over
|
|
51
|
+
* `streamText` or `generateText` — and `runWithFallback` walks the chain,
|
|
52
|
+
* trying each provider in order until one succeeds or the chain is exhausted.
|
|
53
|
+
*/
|
|
54
|
+
declare function runWithFallback<T>(invoke: (model: LanguageModel) => Promise<T>, options?: CreateFallbackModelOptions): Promise<FallbackResult<T>>;
|
|
55
|
+
/**
|
|
56
|
+
* Build `providerOptions` that enable prompt caching across providers.
|
|
57
|
+
*
|
|
58
|
+
* - Anthropic: explicit `cacheControl: { type: 'ephemeral' }` on the system
|
|
59
|
+
* message — 90% cost reduction on cached prefix tokens.
|
|
60
|
+
* - OpenAI: prompt caching is AUTOMATIC for prompts ≥1024 tokens with a
|
|
61
|
+
* stable prefix. No flag needed — but callers MUST keep the system prompt
|
|
62
|
+
* + tools FIRST and dynamic user content LAST, otherwise the cache is
|
|
63
|
+
* invalidated on every call.
|
|
64
|
+
* - OpenRouter: passes provider options through transparently.
|
|
65
|
+
*/
|
|
66
|
+
declare function withAnthropicCacheControl(): {
|
|
67
|
+
anthropic: {
|
|
68
|
+
cacheControl: {
|
|
69
|
+
type: "ephemeral";
|
|
70
|
+
};
|
|
71
|
+
};
|
|
72
|
+
};
|
|
73
|
+
/**
|
|
74
|
+
* Wraps the system message in a structured cache-control hint.
|
|
75
|
+
* Returns the messages array unchanged if no system text is provided.
|
|
76
|
+
*
|
|
77
|
+
* IMPORTANT: keep stable content (system prompt + tool defs) FIRST,
|
|
78
|
+
* dynamic content (user query) LAST — required for both Anthropic explicit
|
|
79
|
+
* caching AND OpenAI automatic caching to hit.
|
|
80
|
+
*/
|
|
81
|
+
declare function buildSystemWithCache(systemPrompt: string): {
|
|
82
|
+
role: "system";
|
|
83
|
+
content: string;
|
|
84
|
+
providerOptions: ReturnType<typeof withAnthropicCacheControl>;
|
|
85
|
+
};
|
|
86
|
+
interface EmbeddingFallbackOptions {
|
|
87
|
+
chain?: readonly FallbackProviderName[];
|
|
88
|
+
model?: string;
|
|
89
|
+
filterAvailable?: boolean;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Run an AI SDK embedding call against the configured embedding fallback chain.
|
|
93
|
+
*
|
|
94
|
+
* The caller provides an `invoke(model)` function — usually a closure over
|
|
95
|
+
* `embed` or `embedMany` from the `ai` package — and this helper walks the
|
|
96
|
+
* embedding-capable chain, trying each provider until one succeeds.
|
|
97
|
+
*/
|
|
98
|
+
declare function runEmbedWithFallback<T>(invoke: (model: EmbeddingModel) => Promise<T>, options?: EmbeddingFallbackOptions): Promise<FallbackResult<T>>;
|
|
99
|
+
|
|
100
|
+
export { type CreateFallbackModelOptions, type EmbeddingFallbackOptions, type FallbackResult, buildSystemWithCache, filterAvailableProviders, isRetryableError, runEmbedWithFallback, runWithFallback, withAnthropicCacheControl };
|
package/dist/fallback.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import {
|
|
2
|
+
buildSystemWithCache,
|
|
3
|
+
filterAvailableProviders,
|
|
4
|
+
isRetryableError,
|
|
5
|
+
runEmbedWithFallback,
|
|
6
|
+
runWithFallback,
|
|
7
|
+
withAnthropicCacheControl
|
|
8
|
+
} from "./chunk-C4CC5UEF.js";
|
|
9
|
+
import "./chunk-HVLFZW6E.js";
|
|
10
|
+
import "./chunk-FCXWOXII.js";
|
|
11
|
+
export {
|
|
12
|
+
buildSystemWithCache,
|
|
13
|
+
filterAvailableProviders,
|
|
14
|
+
isRetryableError,
|
|
15
|
+
runEmbedWithFallback,
|
|
16
|
+
runWithFallback,
|
|
17
|
+
withAnthropicCacheControl
|
|
18
|
+
};
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Image / video generation modality for `@nebutra/agents`.
|
|
3
|
+
*
|
|
4
|
+
* The text + embedding modalities wrap the Vercel AI SDK. Image / video
|
|
5
|
+
* generation is a *new modality on the same provider layer*: providers are
|
|
6
|
+
* env-key gated exactly like the LLM fallback chain (see `fallback.ts`), so
|
|
7
|
+
* single-provider — or zero-provider (mock) — deploys just work.
|
|
8
|
+
*
|
|
9
|
+
* Generation is tenant-scoped: every call carries a {@link GenerationContext}
|
|
10
|
+
* so downstream metering / audit can attribute units to an organization.
|
|
11
|
+
*/
|
|
12
|
+
/** What a provider can produce. */
|
|
13
|
+
type GenerationModality = "image" | "video";
|
|
14
|
+
/** Tenant-scoped attribution for a generation call (mirrors AgentContext). */
|
|
15
|
+
interface GenerationContext {
|
|
16
|
+
readonly tenantId: string;
|
|
17
|
+
readonly userId: string;
|
|
18
|
+
/** Optional logical grouping (e.g. a canvas / conversation id). */
|
|
19
|
+
readonly conversationId?: string;
|
|
20
|
+
}
|
|
21
|
+
interface ImageGenerationRequest {
|
|
22
|
+
readonly prompt: string;
|
|
23
|
+
/** Pixel width — defaults to 1024. */
|
|
24
|
+
readonly width?: number;
|
|
25
|
+
/** Pixel height — defaults to 1024. */
|
|
26
|
+
readonly height?: number;
|
|
27
|
+
/** Optional model id / preset; provider-specific passthrough. */
|
|
28
|
+
readonly model?: string;
|
|
29
|
+
/** Reference images (data: URI or URL) for edit / variation flows. */
|
|
30
|
+
readonly inputImages?: readonly string[];
|
|
31
|
+
}
|
|
32
|
+
interface VideoGenerationRequest {
|
|
33
|
+
readonly prompt: string;
|
|
34
|
+
/** Clip length in seconds — defaults to 5. */
|
|
35
|
+
readonly durationSeconds?: number;
|
|
36
|
+
readonly width?: number;
|
|
37
|
+
readonly height?: number;
|
|
38
|
+
readonly model?: string;
|
|
39
|
+
/** Optional first-frame image (data: URI or URL). */
|
|
40
|
+
readonly inputImage?: string;
|
|
41
|
+
}
|
|
42
|
+
interface GenerationResult {
|
|
43
|
+
readonly modality: GenerationModality;
|
|
44
|
+
/** e.g. "image/svg+xml", "image/png", "video/mp4". */
|
|
45
|
+
readonly mimeType: string;
|
|
46
|
+
/** `data:` URI (mock / inline) or a remote URL the caller can fetch. */
|
|
47
|
+
readonly url: string;
|
|
48
|
+
readonly width: number;
|
|
49
|
+
readonly height: number;
|
|
50
|
+
/** Provider that actually produced the asset. */
|
|
51
|
+
readonly providerName: string;
|
|
52
|
+
/** Model id reported by the provider. */
|
|
53
|
+
readonly model: string;
|
|
54
|
+
/**
|
|
55
|
+
* Best-effort billable units for `@nebutra/metering` (e.g. 1 image,
|
|
56
|
+
* N seconds of video). Callers decide the meter mapping.
|
|
57
|
+
*/
|
|
58
|
+
readonly usage: {
|
|
59
|
+
readonly units: number;
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* A generation backend. `envKey` mirrors the LLM provider gating: when the
|
|
64
|
+
* variable is absent the provider is filtered out of the chain. `null` means
|
|
65
|
+
* "always available" — reserved for the deterministic mock provider so CI and
|
|
66
|
+
* flag-gated demos never need a paid secret.
|
|
67
|
+
*/
|
|
68
|
+
interface GenerationProvider {
|
|
69
|
+
readonly name: string;
|
|
70
|
+
readonly envKey: string | null;
|
|
71
|
+
readonly capabilities: readonly GenerationModality[];
|
|
72
|
+
generateImage?(req: ImageGenerationRequest, ctx: GenerationContext): Promise<GenerationResult>;
|
|
73
|
+
generateVideo?(req: VideoGenerationRequest, ctx: GenerationContext): Promise<GenerationResult>;
|
|
74
|
+
}
|
|
75
|
+
interface GenerationCallOptions {
|
|
76
|
+
/**
|
|
77
|
+
* Ordered provider-name preference. Unknown / unavailable names are skipped.
|
|
78
|
+
* Defaults to `GENERATION_FALLBACK_CHAIN` env (comma-separated) then registry
|
|
79
|
+
* order, always ending at `mock` so a result is guaranteed.
|
|
80
|
+
*/
|
|
81
|
+
readonly chain?: readonly string[];
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Deterministic mock generation provider.
|
|
86
|
+
*
|
|
87
|
+
* Always available (`envKey: null`) so CI and flag-gated demos never need a
|
|
88
|
+
* paid secret. Output is a stable, content-addressed SVG `data:` URI: the same
|
|
89
|
+
* prompt + size always yields byte-identical bytes, which makes canvas
|
|
90
|
+
* placement and websocket-sync tests deterministic.
|
|
91
|
+
*
|
|
92
|
+
* Wiring a real provider (Replicate / OpenAI images / Volces) later is purely
|
|
93
|
+
* additive — register it with a non-null `envKey` and it takes priority over
|
|
94
|
+
* `mock` in the fallback chain whenever its key is present.
|
|
95
|
+
*/
|
|
96
|
+
|
|
97
|
+
declare const mockGenerationProvider: GenerationProvider;
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Image / video generation modality — public surface.
|
|
101
|
+
*
|
|
102
|
+
* Mirrors the LLM fallback design (`fallback.ts`): an ordered provider chain,
|
|
103
|
+
* filtered to providers whose `envKey` is present, with `mock` as the
|
|
104
|
+
* guaranteed terminal so a result is always produced. Retryable failures
|
|
105
|
+
* (429 / 5xx / network) rotate to the next provider via `isRetryableError`.
|
|
106
|
+
*/
|
|
107
|
+
|
|
108
|
+
declare function registerGenerationProvider(provider: GenerationProvider): void;
|
|
109
|
+
/** Test helper — restores the registry to just the mock provider. */
|
|
110
|
+
declare function _resetGenerationRegistry(): void;
|
|
111
|
+
/** Provider names available for a modality, in resolved priority order. */
|
|
112
|
+
declare function listGenerationProviders(modality: GenerationModality, options?: GenerationCallOptions): string[];
|
|
113
|
+
/**
|
|
114
|
+
* Generate an image. Always resolves (falls back to the deterministic mock).
|
|
115
|
+
*/
|
|
116
|
+
declare function generateImage(req: ImageGenerationRequest, ctx: GenerationContext, options?: GenerationCallOptions): Promise<GenerationResult>;
|
|
117
|
+
/**
|
|
118
|
+
* Generate a video (or, in mock mode, a deterministic poster frame).
|
|
119
|
+
*/
|
|
120
|
+
declare function generateVideo(req: VideoGenerationRequest, ctx: GenerationContext, options?: GenerationCallOptions): Promise<GenerationResult>;
|
|
121
|
+
|
|
122
|
+
export { type GenerationCallOptions, type GenerationContext, type GenerationModality, type GenerationProvider, type GenerationResult, type ImageGenerationRequest, type VideoGenerationRequest, _resetGenerationRegistry, generateImage, generateVideo, listGenerationProviders, mockGenerationProvider, registerGenerationProvider };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import {
|
|
2
|
+
_resetGenerationRegistry,
|
|
3
|
+
generateImage,
|
|
4
|
+
generateVideo,
|
|
5
|
+
listGenerationProviders,
|
|
6
|
+
mockGenerationProvider,
|
|
7
|
+
registerGenerationProvider
|
|
8
|
+
} from "../chunk-HZQXXUKB.js";
|
|
9
|
+
import "../chunk-C4CC5UEF.js";
|
|
10
|
+
import "../chunk-HVLFZW6E.js";
|
|
11
|
+
import "../chunk-FCXWOXII.js";
|
|
12
|
+
export {
|
|
13
|
+
_resetGenerationRegistry,
|
|
14
|
+
generateImage,
|
|
15
|
+
generateVideo,
|
|
16
|
+
listGenerationProviders,
|
|
17
|
+
mockGenerationProvider,
|
|
18
|
+
registerGenerationProvider
|
|
19
|
+
};
|