Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/features/agnes-30-flash-catalog.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- feat(providers): **list Agnes 3.0 Flash as the current free chat model, drop retired 1.5 Flash, add Image 2.0/2.5 Flash plus Video 2.5/2.5 Flash, and discover the live `/v1/models` catalog (including the CN host `api.agnes-ai.cn`).** `agnes-1.5-flash` now forwards to `agnes-3.0-flash`. Video 2.5 polls `GET /v1/videos/{id}` (not the V2.0 `/agnesapi` contract). Live `/v1/models` (2026-09-09) no longer serves 1.5; the wiki marks it deprecated. 3.0 Flash is 512K context / 65,536 max output, same window as 2.5. CN-region keys use the existing per-connection base-URL field, default stays `apihub.agnes-ai.com`.
6 changes: 4 additions & 2 deletions open-sse/config/freeModelCatalog.data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import type { FreeModelBudget } from "./freeModelCatalog.ts";
* rewrites file timestamps on every deploy, which would report a months-old
* catalog as "updated today". Bump this whenever the entries below change.
*/
export const FREE_CATALOG_CURATED_AT = "2026-09-03";
export const FREE_CATALOG_CURATED_AT = "2026-09-09";

export const FREE_MODEL_BUDGETS: FreeModelBudget[] = [
{ provider: "agentrouter", modelId: "claude-opus-4-8", displayName: "Claude Opus 4.8", monthlyTokens: 0, creditTokens: 200000000, freeType: "one-time-initial", poolKey: "agentrouter", tos: "caution" },
Expand Down Expand Up @@ -458,9 +458,11 @@ export const FREE_MODEL_BUDGETS: FreeModelBudget[] = [
{ provider: "ovhcloud", modelId: "Qwen3.6-27B", displayName: "Qwen3.6 27B (OVH anonymous)", monthlyTokens: 0, creditTokens: 0, freeType: "keyless", poolKey: "ovhcloud-anon", tos: "ok" },
{ provider: "ovhcloud", modelId: "Mistral-Small-3.2-24B-Instruct-2506", displayName: "Mistral Small 3.2 24B (OVH anonymous)", monthlyTokens: 0, creditTokens: 0, freeType: "keyless", poolKey: "ovhcloud-anon", tos: "ok" },
{ provider: "ovhcloud", modelId: "Qwen2.5-VL-72B-Instruct", displayName: "Qwen2.5 VL 72B (OVH anonymous)", monthlyTokens: 0, creditTokens: 0, freeType: "keyless", poolKey: "ovhcloud-anon", tos: "ok" },
{ provider: "agnes", modelId: "agnes-1.5-flash", displayName: "Agnes 1.5 Flash", monthlyTokens: 0, creditTokens: 0, freeType: "recurring-uncapped", poolKey: "agnes-free", tos: "ok" },
// evidence: public-page wiki.agnes-ai.com/docs/pricing 2026-09-09 current $0
// for 2.0/2.5 flash; live GET /v1/models lists 3.0-flash (1.5-flash 503, retired).
{ provider: "agnes", modelId: "agnes-2.0-flash", displayName: "Agnes 2.0 Flash", monthlyTokens: 0, creditTokens: 0, freeType: "recurring-uncapped", poolKey: "agnes-free", tos: "ok" },
{ provider: "agnes", modelId: "agnes-2.5-flash", displayName: "Agnes 2.5 Flash", monthlyTokens: 0, creditTokens: 0, freeType: "recurring-uncapped", poolKey: "agnes-free", tos: "ok" },
{ provider: "agnes", modelId: "agnes-3.0-flash", displayName: "Agnes 3.0 Flash", monthlyTokens: 0, creditTokens: 0, freeType: "recurring-uncapped", poolKey: "agnes-free", tos: "ok" },
{ provider: "glm", modelId: "glm-4.7-flash", displayName: "GLM-4.7-Flash", monthlyTokens: 0, creditTokens: 0, freeType: "recurring-uncapped", poolKey: "zhipu-flash-free", tos: "ok" },
{ provider: "glm", modelId: "glm-4.5-flash", displayName: "GLM-4.5-Flash", monthlyTokens: 0, creditTokens: 0, freeType: "recurring-uncapped", poolKey: "zhipu-flash-free", tos: "ok" },
{ provider: "navy", modelId: "shared-pool", displayName: "NavyAI free pool (150K tokens/day, shared)", monthlyTokens: 4500000, creditTokens: 0, freeType: "recurring-daily", poolKey: "navy-free", tos: "ok" },
Expand Down
12 changes: 12 additions & 0 deletions open-sse/config/imageRegistry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,12 +168,24 @@ export const IMAGE_PROVIDERS: Record<string, ImageProviderConfig> = {
authHeader: "bearer",
format: "agnes-image",
models: [
{
id: "agnes-image-2.0-flash",
name: "Agnes Image 2.0 Flash",
inputModalities: ["text", "image"],
description: "Agnes text-to-image, image-to-image, and multi-image composition model",
},
{
id: "agnes-image-2.1-flash",
name: "Agnes Image 2.1 Flash",
inputModalities: ["text", "image"],
description: "Agnes text-to-image, image-to-image, and multi-image composition model",
},
{
id: "agnes-image-2.5-flash",
name: "Agnes Image 2.5 Flash",
inputModalities: ["text", "image"],
description: "Agnes text-to-image, image-to-image, and multi-image composition model",
},
],
supportedSizes: ["1K", "2K", "3K", "4K"],
},
Expand Down
19 changes: 12 additions & 7 deletions open-sse/config/providers/registry/agnes/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,34 @@ export const agnesProvider: RegistryEntry = {
format: "openai",
executor: "default",
baseUrl: "https://apihub.agnes-ai.com/v1/chat/completions",
modelsUrl: "https://apihub.agnes-ai.com/v1/models",
authType: "apikey",
authHeader: "bearer",
models: [
{
id: "agnes-1.5-flash",
name: "Agnes 1.5 Flash",
id: "agnes-2.0-flash",
name: "Agnes 2.0 Flash",
contextLength: 262144,
maxOutputTokens: 65536,
supportsReasoning: true,
supportsVision: true,
toolCalling: true,
},
{
id: "agnes-2.0-flash",
name: "Agnes 2.0 Flash",
contextLength: 262144,
id: "agnes-2.5-flash",
name: "Agnes 2.5 Flash",
contextLength: 524288,
maxOutputTokens: 65536,
supportsReasoning: true,
supportsVision: true,
toolCalling: true,
interleavedField: "reasoning_content",
},
{
id: "agnes-2.5-flash",
name: "Agnes 2.5 Flash",
// Wiki (2026-09-10) lists agnes-3.0-flash at 512K context / 65,536 max
// output, same window as 2.5 Flash. Live GET /v1/models includes it.
id: "agnes-3.0-flash",
name: "Agnes 3.0 Flash",
contextLength: 524288,
maxOutputTokens: 65536,
supportsReasoning: true,
Expand Down
12 changes: 12 additions & 0 deletions open-sse/config/videoRegistry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ interface VideoModel {
isMarket?: boolean;
supportedSizes?: string[];
mediaCapabilities?: Record<string, unknown>;
/** Override the provider-level job preset for this model. */
jobPreset?: string;
}

interface VideoProvider {
Expand Down Expand Up @@ -48,6 +50,16 @@ export const VIDEO_PROVIDERS: Record<string, VideoProvider> = {
id: "agnes-video-v2.0",
name: "Agnes Video V2.0",
},
{
id: "agnes-video-2.5-flash",
name: "Agnes Video 2.5 Flash",
jobPreset: "agnes-video-2.5-job",
},
{
id: "agnes-video-2.5",
name: "Agnes Video 2.5",
jobPreset: "agnes-video-2.5-job",
},
],
},

Expand Down
7 changes: 5 additions & 2 deletions open-sse/handlers/videoGeneration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -195,10 +195,13 @@ export async function handleVideoGeneration({ body, credentials, log, resolvedPr
log,
});
}
if (getVideoJobPreset(providerConfig.format)) {
const modelJobPreset = providerConfig.models.find((entry) => entry.id === model)?.jobPreset;
const jobPresetName =
typeof modelJobPreset === "string" && modelJobPreset ? modelJobPreset : providerConfig.format;
if (getVideoJobPreset(jobPresetName)) {
return handleVideoJobGeneration({
model,
presetName: providerConfig.format,
presetName: jobPresetName,
body,
credentials,
log,
Expand Down
30 changes: 30 additions & 0 deletions open-sse/handlers/videoGeneration/job.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,36 @@ const VIDEO_JOB_PRESETS: Record<string, VideoJobPreset> = {
maxPolls: 60,
pollIntervalMs: 2000,
},
"agnes-video-2.5-job": {
id: "agnes-video-2.5-job",
displayName: "Agnes Video 2.5",
authHeaderName: "Authorization",
authScheme: "bearer",
// Wiki 2026-09-09 + live probe: POST /v1/videos returns `id`, poll GET /v1/videos/{id}, result `url`.
// seconds is a string. Do not reuse agnes-video-job (video_id + /agnesapi).
baseUrlFallback: "https://apihub.agnes-ai.com",
submit: {
method: "POST",
path: "/v1/videos",
buildBody: ({ model, prompt, extras }) => {
const seconds = extras.seconds;
return {
model,
prompt,
...extras,
...(typeof seconds === "number" ? { seconds: String(seconds) } : {}),
};
},
},
taskIdPath: "id",
poll: { pathTemplate: "/v1/videos/{taskId}" },
statusPath: "status",
statusDone: ["completed"],
statusFailed: ["failed"],
resultPath: "url",
maxPolls: 60,
pollIntervalMs: 2000,
},
"muapi-video-job": {
id: "muapi-video-job",
displayName: "muapi.ai",
Expand Down
6 changes: 5 additions & 1 deletion open-sse/services/modelDeprecation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,13 @@ const BUILT_IN_ALIASES: Record<string, string> = {
// Llama short aliases
"llama-3.3": "llama-3.3-70b-versatile",
"llama-3-70b": "llama-3.3-70b-versatile",
// #11503: llama3-8b-8192 was deprecated by Groq on 2025-08-30 and is not in the
// #11503: llama3-8b-8192 deprecated on Groq 2025-08-30 and not in the
// catalog; llama-3.1-8b-instant is the replacement Groq names.
"llama-3-8b": "llama-3.1-8b-instant",

// Agnes 1.5 Flash: wiki marks deprecated; live GET /v1/models
// (2026-09-09) no longer lists it (503 no channel).
"agnes-1.5-flash": "agnes-3.0-flash",
};

// ── Custom Aliases (persisted via Settings API) ─────────────────────────────
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,10 @@ export const CONFIGURABLE_BASE_URL_PROVIDERS = new Set([
// the existing override affordance for these two ids.
"kimi",
"moonshot",
// Agnes CN-region keys (agnes-ai.cn) use a separate host from
// the international apihub.agnes-ai.com default. Same always-on field as
// #7447 Kimi/Moonshot so Add-connection can point at api.agnes-ai.cn.
"agnes",
]);

export const DEFAULT_PROVIDER_BASE_URLS: Record<string, string> = {
Expand All @@ -261,6 +265,7 @@ export const DEFAULT_PROVIDER_BASE_URLS: Record<string, string> = {
// before; a CN-region user overrides it (see placeholder hint below).
kimi: "https://api.moonshot.ai/v1",
moonshot: "https://api.moonshot.ai/v1",
agnes: "https://apihub.agnes-ai.com/v1",
};

export function getLocalProviderMetadata(providerId?: string | null) {
Expand Down Expand Up @@ -372,6 +377,8 @@ export function getProviderBaseUrlPlaceholder(providerId?: string | null) {
// #7447 — surfaces the CN-region alternative host as the placeholder
// example (mirrors the siliconflow.com/siliconflow.cn pattern above).
return "https://api.moonshot.cn/v1";
case "agnes":
return "https://api.agnes-ai.cn/v1";
default:
return "";
}
Expand Down
5 changes: 5 additions & 0 deletions src/app/api/providers/[id]/models/discovery/providerSets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,11 @@ export const NAMED_OPENAI_STYLE_PROVIDERS = new Set([
// (11 chat-capable). Live fetch keeps it fresh; the registry seed stays as the
// offline fallback.
"logfare",
// Agnes hosts a live OpenAI-style /v1/models catalog on both the
// international (apihub.agnes-ai.com) and CN (api.agnes-ai.cn) hosts.
// Without this, sync-models serves the static registry seed and CN
// connections never discover 2.5/3.0 Flash.
"agnes",
]);

export function isNamedOpenAIStyleProvider(provider: string): boolean {
Expand Down
10 changes: 8 additions & 2 deletions src/shared/validation/schemas/provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -308,13 +308,19 @@ export const providerModelMutationSchema = z.object({
.optional(),
// #9820: optional async video-generation job preset for a custom
// OpenAI-compatible provider whose /videos surface is a submit→poll API
// (agnes-video-job, muapi-video-job, sora-job). Persisted on the custom model
// (agnes-video-job, agnes-video-2.5-job, muapi-video-job, sora-job). Persisted on the custom model
// row; the /v1/videos/generations handler branches on it between the
// synchronous OpenAI-compatible path and the job/poll path. `"openai-video"`
// is a legacy no-op value that keeps the sync handler selected.
generationConfig: z
.object({
preset: z.enum(["agnes-video-job", "muapi-video-job", "sora-job", "openai-video"]),
preset: z.enum([
"agnes-video-job",
"agnes-video-2.5-job",
"muapi-video-job",
"sora-job",
"openai-video",
]),
})
.optional(),
});
Expand Down
Loading
Loading