qlogicagent 2.10.3 → 2.10.5

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.
@@ -1,10 +1,8 @@
1
1
  /**
2
- * Builtin provider definitions 鈥?hardcoded fallback list (~30 providers).
2
+ * Curated Provider Core model catalog.
3
3
  *
4
- * This is Layer 1 (lowest priority) of the three-layer merge strategy.
5
- * Used when remote model catalog is unavailable.
6
- *
7
- * Aligned with Hermes hermes_cli/models.py hardcoded fallback.
4
+ * This is the single source used by qlogicagent direct mode and llmrouter's
5
+ * model catalog API. External broad catalogs are intentionally not merged in.
8
6
  */
9
7
  import type { ProviderDef } from "./provider-def.js";
10
8
  export declare const BUILTIN_PROVIDERS: ProviderDef[];
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * Provides: ProviderDef + LLMTransport + ProviderRegistry + LLMClient factory
5
5
  */
6
- export type { ProviderDef, ModelInfo, TransportType, AuthType, MediaCapability, MediaCapabilities, VideoCapabilities, ImageCapabilities, MusicCapabilities, TtsCapabilities, ThreeDCapabilities, SttCapabilities, EmbeddingCapabilities, VideoUnderstandingCapabilities, ImageUnderstandingCapabilities, VoiceCloneCapabilities, RerankCapabilities, DocumentParsingCapabilities, RealtimeAudioCapabilities, VideoOperation, ImageOperation, MusicOperation, TtsOperation, ThreeDOperation } from "./provider-def.js";
6
+ export type { ProviderDef, ModelInfo, TransportType, AuthType, MediaCapability, MediaCapabilities, VideoCapabilities, ImageCapabilities, MusicCapabilities, TtsCapabilities, ThreeDCapabilities, SttCapabilities, EmbeddingCapabilities, VideoUnderstandingCapabilities, ImageUnderstandingCapabilities, VoiceCloneCapabilities, RerankCapabilities, DocumentParsingCapabilities, RealtimeAudioCapabilities, VideoOperation, ImageOperation, MusicOperation, TtsOperation, ThreeDOperation, ProviderVariantKind, ProviderBillingChannelKind, ProviderVariantCapability } from "./provider-def.js";
7
7
  export type { LLMTransport, LLMRequest, LLMChunk, AccumulatedToolCall, } from "./transport.js";
8
8
  export { accumulateToolCalls } from "./transport.js";
9
9
  export type { ChatMessage, ChatMessageRole, ThinkingBlock, ToolCallMessage, ToolDefinition } from "./wire-types.js";
@@ -16,7 +16,7 @@ export { MediaClient, type MediaClientConfig, type ResolvedMediaModel } from "./
16
16
  export type { ProviderToolAPI, WebSearchResult, ReaderResult, TokenizerResult, ModerationResult, ProviderToolCapability } from "./provider-tool-api.js";
17
17
  export { ProviderRegistry } from "./provider-registry.js";
18
18
  export { BUILTIN_PROVIDERS } from "./builtin-providers.js";
19
- export { ModelCatalog } from "./model-catalog.js";
19
+ export { ProviderVariantResolver, type ProviderVariantResolverInput, type ProviderVariantResolution, type RequestedProviderProtocol } from "./provider-variant-resolver.js";
20
20
  export type { LLMClientConfig, LLMClient } from "./llm-client.js";
21
21
  export { createLLMClient } from "./llm-client.js";
22
22
  export { OpenAIChatTransport } from "./transports/openai-chat.js";
@@ -4,14 +4,14 @@
4
4
  * Aligned with Hermes `ProviderDef` dataclass pattern:
5
5
  * id + name + transport type + baseUrl + auth config + model list
6
6
  *
7
- * Three-layer merge strategy (Layer 3 > Layer 2 > Layer 1):
8
- * Layer 1: builtin-providers.ts hardcoded (fallback)
9
- * Layer 2: model-catalog.ts remote (models.dev)
10
- * Layer 3: user config (from agent.turn.config)
7
+ * Single curated model catalog plus optional user provider overrides.
11
8
  */
12
9
  export type TransportType = "openai-chat" | "openai-responses" | "anthropic-messages" | "volcengine-responses" | "gemini-generatecontent";
13
10
  export type AuthType = "bearer" | "x-api-key" | "none";
14
11
  export type MediaCapability = "image" | "video" | "music" | "music_realtime" | "tts" | "3d" | "stt" | "embedding" | "video_understanding" | "image_understanding" | "voice_clone" | "rerank" | "document_parsing" | "realtime_audio" | "realtime_video";
12
+ export type ProviderVariantKind = "standard" | "openai-compatible" | "anthropic-compatible" | "coding-plan" | "media-plan" | "realtime";
13
+ export type ProviderBillingChannelKind = "paygo" | "plan" | "discount" | "official";
14
+ export type ProviderVariantCapability = "thinking" | "reasoning_split" | "tool_stream" | "builtin_tools" | "vision" | "media" | "coding" | "realtime";
15
15
  export type VideoOperation = "text2video" | "img2video" | "video2video" | "edit" | "merge" | "upscale";
16
16
  export type ImageOperation = "text2image" | "img2img" | "inpainting" | "outpainting";
17
17
  export type MusicOperation = "text2music" | "cover" | "realtime";
@@ -159,6 +159,12 @@ export interface ProviderDef {
159
159
  * Defaults to provider id if unset.
160
160
  */
161
161
  group?: string;
162
+ /** Technical protocol variant kind for resolver ranking. */
163
+ variantKind?: ProviderVariantKind;
164
+ /** Channel type hint only; commercial cost selection is owned by llmrouter. */
165
+ billingChannelKind?: ProviderBillingChannelKind;
166
+ /** Provider-level capability hints used by ProviderVariantResolver. */
167
+ capabilities?: ProviderVariantCapability[];
162
168
  /** Env var names for API key (priority order) */
163
169
  apiKeyEnvVars: string[];
164
170
  /** Auth header style */
@@ -1,26 +1,22 @@
1
1
  /**
2
- * ProviderRegistry 鈥?two-layer merge registry for LLM providers.
2
+ * ProviderRegistry 鈥?single-source curated registry for LLM providers.
3
3
  *
4
- * Layer 1: builtin-providers.ts hardcoded (lowest priority, ~20 providers)
5
- * Layer 2: model-catalog.ts remote (models.dev 鈥?enriches model metadata)
6
- * Layer 3: user config override (from agent.turn.config 鈥?highest priority)
4
+ * Layer 1: builtin-providers.ts curated providers and models
5
+ * Layer 2: user config override (from agent.turn.config)
7
6
  *
8
- * Merge strategy: Layer 3 > Layer 2 > Layer 1 (later layers override same-id fields)
7
+ * Model IDs are intentionally not enriched from external catalogs. llmrouter and
8
+ * OpenClaw consume the same curated Provider Core catalog, and upstream request
9
+ * IDs are resolved through model aliases/native IDs.
9
10
  *
10
11
  * Aligned with Hermes provider_registry.py.
11
12
  */
12
13
  import type { ModelInfo, ProviderDef } from "./provider-def.js";
13
- import { ModelCatalog } from "./model-catalog.js";
14
14
  export declare class ProviderRegistry {
15
- /** Layer 1: builtin hardcoded providers */
15
+ /** Curated providers and models */
16
16
  private builtins;
17
- /** Layer 2: remote model catalog (models.dev) */
18
- private catalog;
19
- /** Layer 3: user overrides (from agent.turn.config) */
17
+ /** User overrides (from agent.turn.config) */
20
18
  private overrides;
21
- constructor(opts?: {
22
- catalog?: ModelCatalog;
23
- });
19
+ constructor();
24
20
  /**
25
21
  * Apply user config override for a provider.
26
22
  * Typically called when agent.turn.config has baseUrl/apiKey overrides.
@@ -38,7 +34,6 @@ export declare class ProviderRegistry {
38
34
  listProviders(): ProviderDef[];
39
35
  /**
40
36
  * List models for a specific provider.
41
- * Merges: Layer 3 override > Layer 1 builtin > Layer 2 catalog enrichment.
42
37
  */
43
38
  listModels(providerId: string): ModelInfo[];
44
39
  /**
@@ -46,10 +41,6 @@ export declare class ProviderRegistry {
46
41
  * Returns undefined if the model is not found.
47
42
  */
48
43
  getModelInfo(providerId: string, modelId: string): ModelInfo | undefined;
49
- /**
50
- * Trigger background refresh of the remote model catalog.
51
- */
52
- refreshCatalog(): Promise<boolean>;
53
44
  /**
54
45
  * Resolve API key for a provider:
55
46
  * 1. Explicit key (from agent.turn.config)
@@ -0,0 +1,35 @@
1
+ import type { ModelInfo, ProviderBillingChannelKind, ProviderDef, ProviderVariantCapability, ProviderVariantKind, TransportType } from "./provider-def.js";
2
+ import type { ProviderRegistry } from "./provider-registry.js";
3
+ export type RequestedProviderProtocol = TransportType | "openai" | "anthropic";
4
+ export interface ProviderVariantResolverInput {
5
+ publicModel: string;
6
+ requestedProtocol?: RequestedProviderProtocol;
7
+ capabilities?: ProviderVariantCapability[];
8
+ purpose?: string;
9
+ userPreference?: {
10
+ providerIds?: string[];
11
+ preferProviderId?: string;
12
+ preferVariantKind?: ProviderVariantKind;
13
+ };
14
+ }
15
+ export interface ProviderVariantResolution {
16
+ provider: string;
17
+ group: string;
18
+ publicModel: string;
19
+ nativeModelId: string;
20
+ displayName: string;
21
+ transport: TransportType;
22
+ variantKind: ProviderVariantKind;
23
+ billingChannelKind: ProviderBillingChannelKind;
24
+ capabilities: ProviderVariantCapability[];
25
+ score: number;
26
+ reasons: string[];
27
+ providerDef: ProviderDef;
28
+ modelInfo: ModelInfo;
29
+ }
30
+ export declare class ProviderVariantResolver {
31
+ private readonly registry;
32
+ constructor(registry: Pick<ProviderRegistry, "listProviders" | "listModels">);
33
+ resolve(input: ProviderVariantResolverInput): ProviderVariantResolution[];
34
+ resolveBest(input: ProviderVariantResolverInput): ProviderVariantResolution | undefined;
35
+ }
@@ -1,5 +1,5 @@
1
1
  /**
2
- * MiniMax Media Transport 鈥?Music + Video Generation.
2
+ * MiniMax Media Transport 鈥?Music + Video + TTS Generation.
3
3
  *
4
4
  * Music: POST /v1/music_generation (sync or async poll)
5
5
  * Video: POST /v1/video_generation (4 modes: text, image, first-last-frame, subject-ref)
@@ -21,6 +21,7 @@ export declare class MiniMaxMediaTransport implements AsyncMediaTransport {
21
21
  private timeoutMs;
22
22
  constructor(config: MiniMaxMediaConfig);
23
23
  generate(request: MediaRequest, apiKey: string, signal?: AbortSignal): Promise<MediaResult>;
24
+ private generateTTS;
24
25
  private generateMusic;
25
26
  private pollTask;
26
27
  /**
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Qwen (DashScope) Media Transport 鈥?TTS + Video Generation.
2
+ * Qwen (DashScope) Media Transport.
3
3
  *
4
4
  * DashScope async task API pattern:
5
5
  * Submit: POST /api/v1/services/aigc/<service>/generation (X-DashScope-Async: enable)
@@ -9,7 +9,11 @@
9
9
  * Docs: https://help.aliyun.com/zh/model-studio/developer-reference/
10
10
  *
11
11
  * Video models: wan2.7-t2v (text-to-video), wan2.7-i2v (image-to-video)
12
- * TTS models: qwen3-tts-voicedesign, cosyvoice-v2
12
+ * TTS endpoints:
13
+ * Qwen3-TTS: /api/v1/services/aigc/multimodal-generation/generation
14
+ * CosyVoice: /api/v1/services/audio/tts/SpeechSynthesizer
15
+ * Rerank: /api/v1/services/rerank/text-rerank/text-rerank
16
+ * Embedding: /compatible-mode/v1/embeddings
13
17
  */
14
18
  import type { AsyncMediaTransport, MediaRequest, MediaResult, MediaType } from "../media-transport.js";
15
19
  export interface QwenMediaConfig {
@@ -23,6 +27,11 @@ export declare class QwenMediaTransport implements AsyncMediaTransport {
23
27
  private timeoutMs;
24
28
  constructor(config: QwenMediaConfig);
25
29
  generate(request: MediaRequest, apiKey: string, signal?: AbortSignal): Promise<MediaResult>;
30
+ private generateTTS;
31
+ private generateQwenTTS;
32
+ private generateCosyVoiceTTS;
33
+ private generateEmbedding;
34
+ private generateRerank;
26
35
  private pollTask;
27
36
  private generateVideo;
28
37
  /**
@@ -22,6 +22,7 @@ export declare class VolcengineMediaTransport implements AsyncMediaTransport {
22
22
  private timeoutMs;
23
23
  constructor(config: VolcengineMediaConfig);
24
24
  generate(request: MediaRequest, apiKey: string, signal?: AbortSignal): Promise<MediaResult>;
25
+ private generateEmbedding;
25
26
  /**
26
27
  * Check if this transport can handle a given operation.
27
28
  * Video edit/merge/upscale are routed through the same video endpoint.
@@ -76,7 +76,7 @@ export declare class ZhipuMediaTransport implements AsyncMediaTransport {
76
76
  status: string;
77
77
  }>>;
78
78
  /**
79
- * Delete a cloned voice 鈥?DELETE /voice/{voice_id}
79
+ * Delete a cloned voice 鈥?POST /voice/delete
80
80
  */
81
81
  deleteVoice(voiceId: string, apiKey: string, signal?: AbortSignal): Promise<void>;
82
82
  }
@@ -27,6 +27,7 @@ export interface ModelEntry {
27
27
  purposes: ModelPurpose[];
28
28
  baseUrl?: string;
29
29
  enabled: boolean;
30
+ nativeModelId?: string;
30
31
  transport?: string;
31
32
  contextWindow?: number;
32
33
  maxOutput?: number;
@@ -54,6 +55,8 @@ export interface ResolvedModel {
54
55
  export declare const ALL_PURPOSES: ModelPurpose[];
55
56
  export declare class ModelRegistry {
56
57
  private keyPool;
58
+ private coreProviderRegistry;
59
+ private providerVariantResolver;
57
60
  private models;
58
61
  private modelEnabledOverrides;
59
62
  private bindings;
@@ -107,12 +110,17 @@ export declare class ModelRegistry {
107
110
  getTunable<T = unknown>(key: string): T | undefined;
108
111
  getModelInfo(providerId: string, modelId: string): ModelInfo | undefined;
109
112
  getProviderDefaultModel(providerId: string): string | undefined;
113
+ hasConfiguredKeyForProviderVariant(providerId: string): boolean;
114
+ hasAvailableKeyForProviderVariant(providerId: string): boolean;
110
115
  listProviderDefs(): ProviderDef[];
111
116
  resolveProviderApiKey(providerId: string): string | undefined;
112
117
  onChange(callback: RegistryChangeCallback): () => void;
113
118
  getKeyForProvider(providerId: string): string | null;
114
119
  snapshotProviderKeys(): Record<string, string>;
115
120
  private getProviderBaseUrl;
121
+ private acquireKeyForProviderVariant;
122
+ private resolveTechnicalVariant;
123
+ private providerVariantKeyCandidates;
116
124
  private loadModelState;
117
125
  private exportModelState;
118
126
  private emitChange;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "qlogicagent",
3
- "version": "2.10.3",
3
+ "version": "2.10.5",
4
4
  "description": "XiaozhiClaw Agent CLI — subprocess architecture (JSON-RPC over stdio)",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -1,82 +0,0 @@
1
- /**
2
- * ModelCatalog 鈥?remote model directory with disk cache + fallback.
3
- *
4
- * Fetches model metadata from models.dev/api.json (community-maintained,
5
- * comprehensive single-source catalog with 100+ providers).
6
- *
7
- * Two-layer fallback:
8
- * 1. In-memory cache (process-level, TTL check against disk mtime)
9
- * 2. Disk cache (~/.qlogicagent/cache/model_catalog.json)
10
- * 3. Remote fetch (models.dev single endpoint)
11
- * 4. Stale disk cache (if remote fails)
12
- * 5. Empty (caller falls back to builtin-providers.ts hardcoded)
13
- *
14
- * Non-blocking: first startup without cache returns empty immediately,
15
- * triggers background async fetch. Agent uses builtin providers until
16
- * catalog arrives.
17
- */
18
- import type { ModelInfo } from "./provider-def.js";
19
- /** Embedding model metadata from models.dev catalog. */
20
- export interface EmbeddingModelInfo {
21
- id: string;
22
- name: string;
23
- /** Provider-internal ID (e.g. "openai", "qwen") */
24
- providerId: string;
25
- /** Output vector dimensions (from limit.output) */
26
- dimensions: number;
27
- /** Max input context tokens */
28
- maxInputTokens: number;
29
- /** Cost per million input tokens (USD) */
30
- costInput?: number;
31
- /** Model family string from models.dev */
32
- family: string;
33
- }
34
- export declare class ModelCatalog {
35
- private cache;
36
- private cacheDir;
37
- private cacheFile;
38
- private ttlMs;
39
- private fetching;
40
- private lastFetchAttempt;
41
- constructor(opts?: {
42
- cacheDir?: string;
43
- ttlMs?: number;
44
- });
45
- /**
46
- * Get models for a provider. Non-blocking: returns whatever is cached.
47
- * Triggers background refresh if stale.
48
- */
49
- getModels(providerId: string): ModelInfo[];
50
- /**
51
- * Get a single model by provider + model id.
52
- */
53
- getModel(providerId: string, modelId: string): ModelInfo | undefined;
54
- /**
55
- * List all known provider ids from the catalog.
56
- */
57
- listProviderIds(): string[];
58
- /**
59
- * Get embedding models for a provider.
60
- * Returns models sorted by cost (cheapest first, then largest dims).
61
- */
62
- getEmbeddingModels(providerId: string): EmbeddingModelInfo[];
63
- /**
64
- * Get the default embedding model for a provider.
65
- * Picks the cheapest model with >=512 dimensions.
66
- */
67
- getDefaultEmbeddingModel(providerId: string): EmbeddingModelInfo | undefined;
68
- /**
69
- * Get all embedding models across all providers.
70
- */
71
- getAllEmbeddingModels(): Map<string, EmbeddingModelInfo[]>;
72
- /**
73
- * Force refresh from remote. Returns true if successful.
74
- */
75
- refreshCatalog(): Promise<boolean>;
76
- private ensureLoaded;
77
- private isStale;
78
- private loadFromDisk;
79
- private saveToDisk;
80
- private backgroundFetch;
81
- private fetchRemote;
82
- }