qlogicagent 2.10.0 → 2.10.2

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.
Files changed (67) hide show
  1. package/dist/agent.js +16 -16
  2. package/dist/cli.js +263 -264
  3. package/dist/index.js +262 -263
  4. package/dist/types/agent/agent.d.ts +1 -1
  5. package/dist/types/agent/tool-loop.d.ts +1 -1
  6. package/dist/types/agent/types.d.ts +1 -1
  7. package/dist/types/cli/handlers/settings-handler.d.ts +3 -15
  8. package/dist/types/cli/handlers/settings-handler.remote-catalog.test.d.ts +1 -0
  9. package/dist/types/cli/handlers/turn-handler.d.ts +1 -1
  10. package/dist/types/cli/tool-bootstrap.d.ts +3 -3
  11. package/dist/types/index.d.ts +2 -2
  12. package/dist/types/llm/index.d.ts +1 -1
  13. package/dist/types/orchestration/tool-cascade.d.ts +2 -2
  14. package/dist/types/provider-core/adapters/aliyun-oss-file-upload-adapter.d.ts +44 -0
  15. package/dist/types/provider-core/adapters/gemini-file-upload-adapter.d.ts +26 -0
  16. package/dist/types/provider-core/adapters/hub-oss-file-upload-adapter.d.ts +29 -0
  17. package/dist/types/provider-core/adapters/index.d.ts +10 -0
  18. package/dist/types/provider-core/adapters/openai-file-upload-adapter.d.ts +38 -0
  19. package/dist/types/provider-core/adapters/volcengine-file-upload-adapter.d.ts +24 -0
  20. package/dist/types/provider-core/builtin-providers.d.ts +10 -0
  21. package/dist/types/provider-core/constants.d.ts +1 -0
  22. package/dist/types/provider-core/credentials.d.ts +1 -0
  23. package/dist/types/provider-core/debug-transport.d.ts +12 -0
  24. package/dist/types/provider-core/errors.d.ts +11 -0
  25. package/dist/types/provider-core/events.d.ts +48 -0
  26. package/dist/types/provider-core/file-upload-service.d.ts +68 -0
  27. package/dist/types/provider-core/gemini-schema-utils.d.ts +17 -0
  28. package/dist/types/provider-core/index.d.ts +37 -0
  29. package/dist/types/provider-core/llm-client.d.ts +43 -0
  30. package/dist/types/provider-core/media-client.d.ts +42 -0
  31. package/dist/types/provider-core/media-transport.d.ts +176 -0
  32. package/dist/types/provider-core/media.d.ts +2 -0
  33. package/dist/types/provider-core/model-catalog.d.ts +82 -0
  34. package/dist/types/provider-core/model-detection.d.ts +22 -0
  35. package/dist/types/provider-core/paths.d.ts +2 -0
  36. package/dist/types/provider-core/provider-def.d.ts +214 -0
  37. package/dist/types/provider-core/provider-registry.d.ts +59 -0
  38. package/dist/types/provider-core/provider-tool-api.d.ts +44 -0
  39. package/dist/types/provider-core/retry.d.ts +37 -0
  40. package/dist/types/provider-core/transport.d.ts +281 -0
  41. package/dist/types/provider-core/transports/anthropic-messages.d.ts +65 -0
  42. package/dist/types/provider-core/transports/gemini-cache-api.d.ts +86 -0
  43. package/dist/types/provider-core/transports/gemini-file-api.d.ts +90 -0
  44. package/dist/types/provider-core/transports/gemini-generatecontent.d.ts +56 -0
  45. package/dist/types/provider-core/transports/gemini-lyria-realtime.d.ts +117 -0
  46. package/dist/types/provider-core/transports/gemini-media.d.ts +53 -0
  47. package/dist/types/provider-core/transports/media-resolve.d.ts +50 -0
  48. package/dist/types/provider-core/transports/minimax-media.d.ts +55 -0
  49. package/dist/types/provider-core/transports/openai-chat.d.ts +81 -0
  50. package/dist/types/provider-core/transports/openai-media.d.ts +24 -0
  51. package/dist/types/provider-core/transports/openai-responses.d.ts +63 -0
  52. package/dist/types/provider-core/transports/qwen-media.d.ts +50 -0
  53. package/dist/types/provider-core/transports/realtime-transport.d.ts +183 -0
  54. package/dist/types/provider-core/transports/volcengine-grounding.d.ts +58 -0
  55. package/dist/types/provider-core/transports/volcengine-media.d.ts +93 -0
  56. package/dist/types/provider-core/transports/volcengine-responses.d.ts +64 -0
  57. package/dist/types/provider-core/transports/zhipu-media.d.ts +82 -0
  58. package/dist/types/provider-core/transports/zhipu-tool-api.d.ts +35 -0
  59. package/dist/types/provider-core/wire-types.d.ts +51 -0
  60. package/dist/types/runtime/execution/dream-agent.d.ts +1 -1
  61. package/dist/types/runtime/execution/forked-agent.d.ts +1 -1
  62. package/dist/types/runtime/hooks/context-compression.d.ts +1 -1
  63. package/dist/types/runtime/infra/llmrouter-catalog.d.ts +49 -0
  64. package/dist/types/runtime/infra/model-registry.d.ts +36 -101
  65. package/dist/types/runtime/session/session-persistence.d.ts +1 -1
  66. package/package.json +2 -2
  67. package/dist/types/runtime/infra/builtin-providers.d.ts +0 -36
@@ -0,0 +1,93 @@
1
+ /**
2
+ * Volcengine Media Transport 鈥?Doubao Seedream (image), Seedance (video), 3D generation.
3
+ *
4
+ * API reference:
5
+ * Image: POST /v3/images/generations (sync)
6
+ * Video: POST /v3/contents/generations/tasks (async job)
7
+ * 3D: POST /v3/contents/generations/tasks (async job, same endpoint as video)
8
+ *
9
+ * Auth: Authorization: Bearer $ARK_API_KEY
10
+ * Docs: https://www.volcengine.com/docs/82379/1330310
11
+ * https://www.volcengine.com/docs/82379/1874993 (3D)
12
+ */
13
+ import type { AsyncMediaTransport, MediaRequest, MediaResult, MediaType } from "../media-transport.js";
14
+ export interface VolcengineMediaConfig {
15
+ /** Base URL, e.g. "https://ark.cn-beijing.volces.com/api" */
16
+ baseUrl: string;
17
+ timeoutMs?: number;
18
+ }
19
+ export declare class VolcengineMediaTransport implements AsyncMediaTransport {
20
+ readonly supportedTypes: readonly MediaType[];
21
+ private baseUrl;
22
+ private timeoutMs;
23
+ constructor(config: VolcengineMediaConfig);
24
+ generate(request: MediaRequest, apiKey: string, signal?: AbortSignal): Promise<MediaResult>;
25
+ /**
26
+ * Check if this transport can handle a given operation.
27
+ * Video edit/merge/upscale are routed through the same video endpoint.
28
+ */
29
+ canHandle(request: MediaRequest): boolean;
30
+ private generateImage;
31
+ /**
32
+ * Parse streaming image SSE 鈥?yields progressive image quality upgrades.
33
+ * Final event contains the full-quality image URL.
34
+ */
35
+ private parseStreamingImage;
36
+ private generateVideo;
37
+ private generate3D;
38
+ /**
39
+ * Query a single video generation task by ID.
40
+ * GET /v3/contents/generations/tasks/{taskId}
41
+ */
42
+ getTaskStatus(taskId: string, apiKey: string, signal?: AbortSignal): Promise<{
43
+ status: string;
44
+ task: Record<string, unknown>;
45
+ }>;
46
+ /**
47
+ * List video generation tasks with optional filters.
48
+ * GET /v3/contents/generations/tasks
49
+ */
50
+ listVideoTasks(apiKey: string, options?: {
51
+ after?: string;
52
+ limit?: number;
53
+ status?: string;
54
+ }, signal?: AbortSignal): Promise<Record<string, unknown>>;
55
+ /**
56
+ * Cancel or delete a video generation task.
57
+ * DELETE /v3/contents/generations/tasks/{taskId}
58
+ */
59
+ deleteVideoTask(taskId: string, apiKey: string, signal?: AbortSignal): Promise<void>;
60
+ /**
61
+ * Upload a file to Volcengine Files API for reuse in multimodal requests.
62
+ * POST /v3/files
63
+ */
64
+ uploadFile(file: Blob | Buffer, apiKey: string, options?: {
65
+ purpose?: string;
66
+ filename?: string;
67
+ }, signal?: AbortSignal): Promise<{
68
+ id: string;
69
+ status: string;
70
+ }>;
71
+ /**
72
+ * Get file info by ID.
73
+ * GET /v3/files/{fileId}
74
+ */
75
+ getFile(fileId: string, apiKey: string, signal?: AbortSignal): Promise<Record<string, unknown>>;
76
+ /**
77
+ * List uploaded files.
78
+ * GET /v3/files
79
+ */
80
+ listFiles(apiKey: string, options?: {
81
+ after?: string;
82
+ limit?: number;
83
+ purpose?: string;
84
+ order?: "asc" | "desc";
85
+ }, signal?: AbortSignal): Promise<Record<string, unknown>>;
86
+ /**
87
+ * Delete a file.
88
+ * DELETE /v3/files/{fileId}
89
+ */
90
+ deleteFile(fileId: string, apiKey: string, signal?: AbortSignal): Promise<void>;
91
+ private submitTask;
92
+ private pollTask;
93
+ }
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Volcengine Responses API TransportSSE streaming implementation.
3
+ *
4
+ * Implements the fire mountain ark Responses API (`/api/v3/responses`),
5
+ * which is the officially recommended primary path for Doubao LLM text generation
6
+ * (250615+ models: doubao-seed-2.0 series).
7
+ *
8
+ * Key differences from OpenAI Chat Completions:
9
+ * - Endpoint: POST {baseUrl}/v3/responses
10
+ * - Request body uses `input` (not `messages`), `instructions`, `thinking`, `reasoning`
11
+ * - SSE events: response.output_text.delta, response.reasoning_summary_text.delta,
12
+ * response.function_call_arguments.delta, response.completed, etc.
13
+ * - Tool calling: function_call / function_call_output with call_id
14
+ * - Context persistence: previous_response_id for server-side session continuation
15
+ * - Deep thinking: thinking.type (enabled/disabled/auto) + reasoning.effort
16
+ *
17
+ * Docs: https://www.volcengine.com/docs/82379/1399008
18
+ */
19
+ import type { LLMChunk, LLMRequest, LLMTransport } from "../transport.js";
20
+ import type { ProviderQuirks } from "../provider-def.js";
21
+ import type { FileUploadAdapter } from "../file-upload-service.js";
22
+ export interface VolcengineResponsesTransportConfig {
23
+ baseUrl: string;
24
+ extraHeaders?: Record<string, string>;
25
+ timeoutMs?: number;
26
+ quirks?: ProviderQuirks;
27
+ /** File upload adapter for resolving local media URLs via upload instead of base64. */
28
+ fileUploadAdapter?: FileUploadAdapter;
29
+ }
30
+ export declare class VolcengineResponsesTransport implements LLMTransport {
31
+ private baseUrl;
32
+ private extraHeaders;
33
+ private timeoutMs;
34
+ private quirks;
35
+ private fileUploadAdapter?;
36
+ constructor(config: VolcengineResponsesTransportConfig);
37
+ stream(request: LLMRequest, apiKey: string, signal?: AbortSignal): AsyncGenerator<LLMChunk>;
38
+ /**
39
+ * Resolve known Volcengine Responses API incompatibilities:
40
+ * - instructions + caching 閳?drop caching (鎼?0.7)
41
+ * - caching + json_schema 閳?downgrade to json_object (鎼?0.10)
42
+ * - caching + builtin_web_search/image_process 閳?drop those builtin tools
43
+ * Returns a shallow copy with fields adjusted; never mutates the original.
44
+ */
45
+ private resolveConstraints;
46
+ private buildRequestBody;
47
+ private fetchAndStream;
48
+ private handleNonStreamingResponse;
49
+ /**
50
+ * Parse Volcengine Responses API SSE stream.
51
+ *
52
+ * Event format: "event: <type>\ndata: <json>\n\n"
53
+ * Key events:
54
+ * - response.output_text.delta 閳?text content delta
55
+ * - response.reasoning_summary_text.delta 閳?thinking/reasoning text
56
+ * - response.function_call_arguments.delta 閳?tool call arguments streaming
57
+ * - response.output_item.added 閳?new output item started
58
+ * - response.output_item.done 閳?output item completed
59
+ * - response.completed 閳?full response complete with usage
60
+ * - response.failed 閳?error
61
+ */
62
+ private parseSSEStream;
63
+ private processEvent;
64
+ }
@@ -0,0 +1,82 @@
1
+ /**
2
+ * Zhipu (GLM) Media Transport 鈥?CogView (image), CogVideoX (video), TTS, STT, Embedding.
3
+ *
4
+ * API reference (docs.bigmodel.cn):
5
+ * Image sync: POST /images/generations (CogView-4, cogview-3-flash)
6
+ * Image async: POST /async/images/generations (glm-image)
7
+ * Video async: POST /videos/generations (CogVideoX)
8
+ * TTS sync: POST /audio/speech (glm-tts, returns audio bytes)
9
+ * STT sync: POST /audio/transcriptions (glm-asr, multipart/form-data)
10
+ * Embedding: POST /embeddings (embedding-3/2)
11
+ * Async poll: GET /async-result/{id} (unified poll for all async tasks)
12
+ *
13
+ * Base URL: https://open.bigmodel.cn/api/paas/v4
14
+ * Auth: Authorization: Bearer $ZHIPU_API_KEY
15
+ */
16
+ import type { AsyncMediaTransport, MediaRequest, MediaResult, MediaType } from "../media-transport.js";
17
+ export interface ZhipuMediaConfig {
18
+ /** Base URL, e.g. "https://open.bigmodel.cn/api/paas/v4" */
19
+ baseUrl: string;
20
+ timeoutMs?: number;
21
+ }
22
+ export declare class ZhipuMediaTransport implements AsyncMediaTransport {
23
+ readonly supportedTypes: readonly MediaType[];
24
+ private baseUrl;
25
+ private timeoutMs;
26
+ constructor(config: ZhipuMediaConfig);
27
+ generate(request: MediaRequest, apiKey: string, signal?: AbortSignal): Promise<MediaResult>;
28
+ private generateImage;
29
+ /** CogView-4 / cogview-3-flash 鈥?sync, returns URL directly */
30
+ private generateImageSync;
31
+ /** glm-image 鈥?async submit + poll */
32
+ private generateImageAsync;
33
+ private generateVideo;
34
+ private generateTTS;
35
+ private generateSTT;
36
+ private generateEmbedding;
37
+ private generateVoiceClone;
38
+ private generateDocumentParsing;
39
+ private generateRerank;
40
+ private postJSON;
41
+ /**
42
+ * Unified async result polling 鈥?GET /async-result/{id}
43
+ * Returns the result object when task_status === "SUCCESS".
44
+ * Throws on "FAIL" or timeout.
45
+ */
46
+ private pollAsyncResult;
47
+ /**
48
+ * Query a single task status 鈥?GET /async-result/{id}
49
+ * Zhipu uses a unified async result endpoint for all task types.
50
+ */
51
+ getTaskStatus(taskId: string, apiKey: string, signal?: AbortSignal): Promise<{
52
+ status: string;
53
+ task: Record<string, unknown>;
54
+ }>;
55
+ /**
56
+ * List recent tasks 鈥?Zhipu does not have a native list endpoint.
57
+ * Returns empty since individual task query via getTaskStatus() is the primary API.
58
+ */
59
+ listVideoTasks(_apiKey: string, _options?: {
60
+ after?: string;
61
+ limit?: number;
62
+ status?: string;
63
+ }, _signal?: AbortSignal): Promise<Record<string, unknown>>;
64
+ /**
65
+ * Cancel/delete is not supported by Zhipu's async API 鈥?throws informative error.
66
+ * The /async-result/{id} endpoint is read-only.
67
+ */
68
+ deleteVideoTask(_taskId: string, _apiKey: string, _signal?: AbortSignal): Promise<void>;
69
+ /**
70
+ * List cloned voices 鈥?GET /voice/
71
+ * Returns all voice clones for the current user.
72
+ */
73
+ listVoices(apiKey: string, signal?: AbortSignal): Promise<Array<{
74
+ voice_id: string;
75
+ voice_name: string;
76
+ status: string;
77
+ }>>;
78
+ /**
79
+ * Delete a cloned voice 鈥?DELETE /voice/{voice_id}
80
+ */
81
+ deleteVoice(voiceId: string, apiKey: string, signal?: AbortSignal): Promise<void>;
82
+ }
@@ -0,0 +1,35 @@
1
+ /**
2
+ * ZhipuToolAPI 鈥?Zhipu-specific utility endpoints.
3
+ *
4
+ * Implements ProviderToolAPI for Zhipu GLM platform independent APIs:
5
+ * C1: Web Search 鈥?POST /tools/web-search
6
+ * C2: Reader 鈥?POST /tools/reader (extract web page content)
7
+ * C3: Tokenizer 鈥?POST /tokenizer
8
+ * C4: Moderations 鈥?POST /moderations
9
+ *
10
+ * Base URL: https://open.bigmodel.cn/api/paas/v4
11
+ * Auth: Authorization: Bearer $ZHIPU_API_KEY
12
+ *
13
+ * C5 (File Parser) is handled by document_parsing media handler.
14
+ * C6 (Realtime API) requires WebSocket 鈥?out of scope for this interface.
15
+ */
16
+ import type { ProviderToolAPI, ProviderToolCapability, WebSearchResult, ReaderResult, TokenizerResult, ModerationResult } from "../provider-tool-api.js";
17
+ export interface ZhipuToolAPIConfig {
18
+ baseUrl: string;
19
+ apiKey: string;
20
+ timeoutMs?: number;
21
+ }
22
+ export declare class ZhipuToolAPI implements ProviderToolAPI {
23
+ readonly capabilities: readonly ProviderToolCapability[];
24
+ private baseUrl;
25
+ private apiKey;
26
+ private timeoutMs;
27
+ constructor(config: ZhipuToolAPIConfig);
28
+ webSearch(query: string, options?: {
29
+ maxResults?: number;
30
+ }): Promise<WebSearchResult[]>;
31
+ reader(pageUrl: string): Promise<ReaderResult>;
32
+ tokenize(text: string, model: string): Promise<TokenizerResult>;
33
+ moderate(text: string): Promise<ModerationResult>;
34
+ private postJSON;
35
+ }
@@ -0,0 +1,51 @@
1
+ export type ChatMessageRole = "system" | "user" | "assistant" | "tool";
2
+ export interface ThinkingBlock {
3
+ thinking: string;
4
+ signature: string;
5
+ }
6
+ export interface ToolCallMessage {
7
+ id: string;
8
+ type: "function";
9
+ function: {
10
+ name: string;
11
+ arguments: string;
12
+ };
13
+ }
14
+ export interface ChatMessage {
15
+ role: ChatMessageRole;
16
+ content: string | null;
17
+ tool_calls?: ToolCallMessage[];
18
+ tool_call_id?: string;
19
+ name?: string;
20
+ thinkingBlocks?: ThinkingBlock[];
21
+ imageUrls?: string[];
22
+ imageDetail?: "auto" | "low" | "high" | "xhigh";
23
+ imagePixelLimit?: {
24
+ minPixels?: number;
25
+ maxPixels?: number;
26
+ };
27
+ videoUrls?: string[];
28
+ videoFps?: number;
29
+ audioFormat?: "mp3" | "wav" | "aac" | "m4a";
30
+ audioUrls?: string[];
31
+ fileIds?: Array<{
32
+ id: string;
33
+ mimeType?: string;
34
+ size?: number;
35
+ }>;
36
+ }
37
+ export interface ToolDefinition {
38
+ type: "function";
39
+ function: {
40
+ name: string;
41
+ description: string;
42
+ parameters?: Record<string, unknown>;
43
+ };
44
+ meta?: {
45
+ serialOnly?: boolean;
46
+ parallelSafe?: boolean;
47
+ requiresApproval?: boolean;
48
+ isReadOnly?: boolean;
49
+ isDangerous?: boolean;
50
+ };
51
+ }
@@ -12,7 +12,7 @@
12
12
  */
13
13
  import type { DreamTaskState, DreamTurn } from "../../orchestration/subagent/task-types.js";
14
14
  import type { ToolDefinition, ToolInvoker, AgentLogger, HookRegistry } from "../../agent/types.js";
15
- import type { LLMTransport } from "@qlogic/provider-core";
15
+ import type { LLMTransport } from "../../provider-core/index.js";
16
16
  export interface DreamTriggerConfig {
17
17
  /** Minimum hours since last consolidation. Default: 24. */
18
18
  minHours: number;
@@ -18,7 +18,7 @@
18
18
  * Reference: claude-code src/utils/forkedAgent.ts
19
19
  */
20
20
  import type { AgentLogger, ChatMessage, ToolDefinition, ToolInvoker, TokenUsage, TurnEvent, HookRegistry } from "../../agent/types.js";
21
- import type { LLMTransport } from "@qlogic/provider-core";
21
+ import type { LLMTransport } from "../../provider-core/index.js";
22
22
  import type { AgentProgress } from "./progress-tracker.js";
23
23
  /**
24
24
  * Tool permission check function — CC canUseTool parity.
@@ -1,7 +1,7 @@
1
1
  import { ContextEngineRegistry, type CompressibleMessage, type CompressionResult, type CompressionStrategy, type AsyncCompressionStrategy, type SummarizeFn } from "../../orchestration/index.js";
2
2
  import type { HookRegistry } from "./hook-registry.js";
3
3
  import type { RuntimeLogger } from "./hook-registry.js";
4
- import type { LLMTransport } from "@qlogic/provider-core";
4
+ import type { LLMTransport } from "../../provider-core/index.js";
5
5
  /** Rough token estimate: ~4 chars per token for mixed CJK/English. */
6
6
  export declare function estimateTokens(msg: CompressibleMessage): number;
7
7
  /** Estimate total tokens for a message array. */
@@ -0,0 +1,49 @@
1
+ import type { ModelEntry, ModelRegistry } from "./model-registry.js";
2
+ export declare const LLMROUTER_CATALOG_UNAVAILABLE_MESSAGE = "\u65E0\u6CD5\u8FDE\u63A5 llmrouter \u6A21\u578B\u76EE\u5F55";
3
+ export declare class LlmrouterCatalogUnavailableError extends Error {
4
+ constructor(message?: string);
5
+ }
6
+ export interface LlmrouterCatalogProvider {
7
+ id: string;
8
+ name?: string;
9
+ displayName?: string;
10
+ baseUrl?: string;
11
+ base_url?: string;
12
+ transport?: string;
13
+ models?: Array<{
14
+ id?: string;
15
+ }>;
16
+ }
17
+ export interface LlmrouterCatalogModel {
18
+ id: string;
19
+ public_model?: string;
20
+ publicModel?: string;
21
+ provider?: string;
22
+ owned_by?: string;
23
+ native_model_id?: string;
24
+ nativeModelId?: string;
25
+ display_name?: string;
26
+ displayName?: string;
27
+ name?: string;
28
+ category?: string;
29
+ purposes?: string[];
30
+ baseUrl?: string;
31
+ base_url?: string;
32
+ provider_transport?: string;
33
+ providerTransport?: string;
34
+ context_window?: number;
35
+ contextWindow?: number;
36
+ max_output?: number;
37
+ maxOutput?: number;
38
+ stream_required?: boolean;
39
+ streamRequired?: boolean;
40
+ capabilities?: string[];
41
+ pricing?: Record<string, unknown>;
42
+ }
43
+ export declare function listLlmrouterCatalogProviders(): Promise<LlmrouterCatalogProvider[]>;
44
+ export declare function listLlmrouterCatalogModels(): Promise<LlmrouterCatalogModel[]>;
45
+ export declare function providerDisplayName(provider: LlmrouterCatalogProvider): string;
46
+ export declare function providerBaseUrl(provider: LlmrouterCatalogProvider): string | undefined;
47
+ export declare function getLlmrouterCatalogProvider(providerId: string): Promise<LlmrouterCatalogProvider | null>;
48
+ export declare function refreshRegistryFromLlmrouterCatalog(registry: ModelRegistry): Promise<ModelEntry[]>;
49
+ export declare function toModelEntry(model: LlmrouterCatalogModel): ModelEntry | null;
@@ -1,19 +1,24 @@
1
- /**
2
- * Model Registry — centralized model pool + per-purpose binding.
3
- *
4
- * Architecture: User adds Provider keys → enables models → binds each purpose to a model.
5
- * Any code needing a model calls `registry.getActiveModel(purpose)`.
6
- * Turn handler, media handler, STT, TTS — all go through this single source of truth.
7
- *
8
- * Persistence: ~/.qlogicagent/settings.json
9
- * Runtime state (key health, inFlight): in-memory via KeyPool
10
- */
11
- import { type ProviderPoolConfig, type KeyConfig, type LoadBalanceStrategy, type KeyHandle, type PoolStatus } from "./key-pool.js";
12
- import { type ModelInfo, type ProviderDef } from "@qlogic/provider-core";
1
+ import { type KeyConfig, type KeyHandle, type LoadBalanceStrategy, type PoolStatus, type ProviderPoolConfig } from "./key-pool.js";
13
2
  export type RegistryChangeCallback = () => void;
14
- /** Purpose categories for model routing. */
15
3
  export type ModelPurpose = "textGeneration" | "smallModel" | "stt" | "tts" | "imageGeneration" | "imageUnderstanding" | "videoGeneration" | "videoUnderstanding" | "threeDGeneration" | "embedding" | "voiceClone" | "musicGeneration" | "realtimeAudio" | "realtimeVideo";
16
- /** A model entry in the available model pool. */
4
+ export interface ModelInfo {
5
+ id: string;
6
+ name?: string;
7
+ contextWindow?: number;
8
+ maxOutput?: number;
9
+ streamRequired?: boolean;
10
+ vision?: boolean;
11
+ mediaType?: string;
12
+ }
13
+ export interface ProviderDef {
14
+ id: string;
15
+ name: string;
16
+ transport: string;
17
+ baseUrl: string;
18
+ defaultModel?: string;
19
+ group?: string;
20
+ models?: ModelInfo[];
21
+ }
17
22
  export interface ModelEntry {
18
23
  id: string;
19
24
  provider: string;
@@ -22,17 +27,23 @@ export interface ModelEntry {
22
27
  purposes: ModelPurpose[];
23
28
  baseUrl?: string;
24
29
  enabled: boolean;
30
+ transport?: string;
31
+ contextWindow?: number;
32
+ maxOutput?: number;
33
+ streamRequired?: boolean;
34
+ capabilities?: string[];
35
+ pricing?: Record<string, unknown>;
25
36
  }
26
- /** Per-purpose binding: maps purpose → model ID. */
27
37
  export type PurposeBindings = Partial<Record<ModelPurpose, string>>;
28
- /** Persistent settings.json schema (new architecture). */
29
38
  export interface ModelRegistryConfig {
30
39
  providers: ProviderPoolConfig[];
31
- models: ModelEntry[];
40
+ models: Array<{
41
+ id: string;
42
+ enabled?: boolean;
43
+ }>;
32
44
  bindings: PurposeBindings;
33
45
  tunables?: Record<string, unknown>;
34
46
  }
35
- /** Resolved model ready for API call. */
36
47
  export interface ResolvedModel {
37
48
  provider: string;
38
49
  model: string;
@@ -40,34 +51,18 @@ export interface ResolvedModel {
40
51
  baseUrl?: string;
41
52
  keyHandle: KeyHandle;
42
53
  }
54
+ export declare const ALL_PURPOSES: ModelPurpose[];
43
55
  export declare class ModelRegistry {
44
56
  private keyPool;
45
57
  private models;
58
+ private modelEnabledOverrides;
46
59
  private bindings;
47
60
  private settingsPath;
48
61
  private changeListeners;
49
62
  constructor(config?: ModelRegistryConfig);
50
- /**
51
- * Get the currently bound model for a purpose, with a live API key from the pool.
52
- * Returns null if purpose is not bound or no key is available.
53
- *
54
- * IMPORTANT: Caller MUST call result.keyHandle.release({ success, tokens? }) when done.
55
- */
56
63
  getActiveModel(purpose: ModelPurpose): ResolvedModel | null;
57
- /**
58
- * Peek at the bound model for a purpose WITHOUT acquiring a key.
59
- * Useful for UI display, description generation, etc.
60
- */
61
64
  peekActiveModel(purpose: ModelPurpose): ModelEntry | null;
62
- /**
63
- * Check if a purpose has an available model + key (without acquiring).
64
- */
65
65
  isAvailable(purpose: ModelPurpose): boolean;
66
- /**
67
- * Resolve a model name for a purpose, falling back to textGeneration if not bound.
68
- * Returns the raw model string (e.g. "deepseek-v4-flash") or null if nothing configured.
69
- * Does NOT acquire a key — use for cases where the caller already has transport/key.
70
- */
71
66
  resolveModelForPurpose(purpose: ModelPurpose): string | null;
72
67
  addProvider(providerId: string, opts?: {
73
68
  baseUrl?: string;
@@ -89,6 +84,8 @@ export declare class ModelRegistry {
89
84
  addModel(entry: Omit<ModelEntry, "id"> & {
90
85
  id?: string;
91
86
  }): string;
87
+ replaceCatalogModels(entries: ModelEntry[]): void;
88
+ migrateModelIds(aliasToNative: Map<string, string>): void;
92
89
  removeModel(id: string): void;
93
90
  enableModel(id: string): void;
94
91
  disableModel(id: string): void;
@@ -104,84 +101,22 @@ export declare class ModelRegistry {
104
101
  getAllBindings(): Record<string, ModelEntry | null>;
105
102
  getProviderStatus(providerId: string): PoolStatus | null;
106
103
  getAllProviderStatus(): PoolStatus[];
107
- /** Save current config to settings.json. Preserves non-model fields (tunables, theme, etc.). */
108
104
  save(): void;
109
- /** Load config from settings.json. Returns false if file not found or parse error. */
110
105
  load(): boolean;
111
- /** Export full config (for serialization/transfer). */
112
106
  exportConfig(): ModelRegistryConfig;
113
- /**
114
- * Read a tunable value from settings.json tunables section.
115
- * Returns undefined if not set. Does NOT write — read-only accessor.
116
- */
117
107
  getTunable<T = unknown>(key: string): T | undefined;
118
- private _providerRegistry;
119
- private getProviderRegistry;
120
- /**
121
- * Get model metadata (streamRequired, contextWindow, etc.) from the merged
122
- * provider-core registry. Replaces direct `this.registry.getModelInfo(...)`.
123
- */
124
108
  getModelInfo(providerId: string, modelId: string): ModelInfo | undefined;
125
- /**
126
- * Get the default model id for a provider (from builtin-providers).
127
- * Replaces `this.registry.getProvider(provider)?.defaultModel`.
128
- */
129
109
  getProviderDefaultModel(providerId: string): string | undefined;
130
- /**
131
- * List all known provider definitions (builtin + catalog).
132
- * Replaces `this.registry.listProviders()`.
133
- */
134
110
  listProviderDefs(): ProviderDef[];
135
- /**
136
- * Resolve an API key for a provider via env vars (fallback when KeyPool has no key).
137
- * Replaces `this.registry.resolveApiKey(providerId)`.
138
- */
139
111
  resolveProviderApiKey(providerId: string): string | undefined;
140
- /**
141
- * Register a callback to be notified when registry state changes
142
- * (binding change, model add/remove, key change, save/load).
143
- * Returns an unsubscribe function.
144
- */
145
112
  onChange(callback: RegistryChangeCallback): () => void;
146
- private emitChange;
147
- /**
148
- * Snapshot one available key for a provider WITHOUT holding it (for legacy flat-map consumers).
149
- * Returns null if no healthy key exists.
150
- */
151
113
  getKeyForProvider(providerId: string): string | null;
152
- /**
153
- * Snapshot one key per provider (for media tools flat apiKeys map).
154
- */
155
114
  snapshotProviderKeys(): Record<string, string>;
156
115
  private getProviderBaseUrl;
116
+ private loadModelState;
117
+ private exportModelState;
118
+ private emitChange;
157
119
  }
158
- export declare const ALL_PURPOSES: ModelPurpose[];
159
- /**
160
- * Get the global ModelRegistry singleton.
161
- * Lazily loads from settings.json on first access.
162
- */
163
120
  export declare function getModelRegistry(): ModelRegistry;
164
- /**
165
- * Reset the global singleton (for testing or hot-reload).
166
- */
167
121
  export declare function resetModelRegistry(): void;
168
- /**
169
- * Derive which purposes a model supports from its ModelInfo metadata.
170
- * Layer 1: ModelCatalog (models.dev) modalities → purpose mapping.
171
- *
172
- * Priority: mediaType field → vision field → fallback to textGeneration.
173
- */
174
122
  export declare function deriveModelPurposes(model: ModelInfo): ModelPurpose[];
175
- /**
176
- * Layer 3: Name-based heuristic for models not in ModelCatalog or builtin-providers.
177
- */
178
- export declare function heuristicModelPurposes(modelId: string): ModelPurpose[];
179
- /**
180
- * Refresh models from ModelCatalog (remote models.dev + disk cache) for given providers.
181
- * Merges discovered models into the registry without overwriting user-modified entries.
182
- */
183
- export declare function refreshModelsFromCatalog(registry: ModelRegistry, providerIds: string[]): void;
184
- /**
185
- * Force refresh the ModelCatalog from remote, then merge into registry.
186
- */
187
- export declare function forceRefreshCatalog(registry: ModelRegistry, providerIds: string[]): Promise<boolean>;
@@ -107,7 +107,7 @@ export declare function deleteSession(sessionId: string, projectRoot: string): P
107
107
  */
108
108
  export declare function pruneOldSessions(projectRoot: string): Promise<number>;
109
109
  export interface TaskSummaryDeps {
110
- transport: import("@qlogic/provider-core").LLMTransport;
110
+ transport: import("../../provider-core/index.js").LLMTransport;
111
111
  apiKey: string;
112
112
  model: string;
113
113
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "qlogicagent",
3
- "version": "2.10.0",
3
+ "version": "2.10.2",
4
4
  "description": "XiaozhiClaw Agent CLI — subprocess architecture (JSON-RPC over stdio)",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -62,7 +62,6 @@
62
62
  "node": ">=22.0.0"
63
63
  },
64
64
  "dependencies": {
65
- "@qlogic/provider-core": "workspace:*",
66
65
  "better-sqlite3": "^12.10.0",
67
66
  "dotenv": "^17.3.1",
68
67
  "nanoid": "^5.1.5",
@@ -75,6 +74,7 @@
75
74
  "devDependencies": {
76
75
  "@types/better-sqlite3": "^7.6.13",
77
76
  "@types/node": "^22.15.0",
77
+ "@qlogic/provider-core": "workspace:*",
78
78
  "esbuild": "^0.28.0",
79
79
  "tsx": "^4.19.0",
80
80
  "typescript": "^5.9.0",
@@ -1,36 +0,0 @@
1
- /**
2
- * Supported provider metadata for settings RPC.
3
- *
4
- * Bridges provider-core's BUILTIN_PROVIDERS into the ModelPurpose system.
5
- * This is the authoritative list of providers shown in "Add Key" UI.
6
- *
7
- * IMPORTANT: Model lists here are the Layer 2 (offline fallback) data source.
8
- * Layer 1 is ModelCatalog (models.dev remote). These two are the ONLY sources.
9
- */
10
- import type { ModelPurpose } from "./model-registry.js";
11
- export interface KnownModelMeta {
12
- model: string;
13
- displayName: string;
14
- purposes: ModelPurpose[];
15
- baseUrl?: string;
16
- }
17
- export interface SupportedProviderMeta {
18
- id: string;
19
- displayName: string;
20
- baseUrl: string;
21
- defaultRateLimit?: {
22
- rpm?: number;
23
- tpm?: number;
24
- };
25
- knownModels: KnownModelMeta[];
26
- }
27
- /**
28
- * Minimal offline fallback providers.
29
- * Remote catalog (Layer 1) has text generation models; this Layer 2 keeps ONLY
30
- * specialized models that remote may not cover: embedding, TTS, STT, image gen,
31
- * video gen, music gen, 3D gen, realtime voice/video, voice clone.
32
- *
33
- * All providers are kept (for Add Key UI dropdown + baseUrl lookup).
34
- * Text generation / image understanding models are NOT listed here — remote always has them.
35
- */
36
- export declare const SUPPORTED_PROVIDERS: SupportedProviderMeta[];