opc-agent 4.2.0 → 4.2.1

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 (119) hide show
  1. package/.opc/memory.db +0 -0
  2. package/COMPETITIVE-GAP.md +92 -92
  3. package/CONTRIBUTING.md +36 -36
  4. package/README.md +290 -290
  5. package/README.zh-CN.md +269 -269
  6. package/STUDIO-REWRITE-TASK.md +76 -0
  7. package/dist/channels/telegram.d.ts +5 -0
  8. package/dist/channels/telegram.d.ts.map +1 -1
  9. package/dist/channels/telegram.js +108 -0
  10. package/dist/channels/telegram.js.map +1 -1
  11. package/dist/channels/voice.d.ts +71 -97
  12. package/dist/channels/voice.d.ts.map +1 -1
  13. package/dist/channels/voice.js +369 -347
  14. package/dist/channels/voice.js.map +1 -1
  15. package/dist/channels/web.d.ts.map +1 -1
  16. package/dist/channels/web.js +8 -2
  17. package/dist/channels/web.js.map +1 -1
  18. package/dist/channels/wechat.js +6 -6
  19. package/dist/cli/chat.d.ts +4 -1
  20. package/dist/cli/chat.d.ts.map +1 -1
  21. package/dist/cli/chat.js +680 -73
  22. package/dist/cli/chat.js.map +1 -1
  23. package/dist/cli/setup.js +1 -1
  24. package/dist/cli/setup.js.map +1 -1
  25. package/dist/cli.js +373 -280
  26. package/dist/cli.js.map +1 -1
  27. package/dist/core/a2a-http.d.ts +75 -0
  28. package/dist/core/a2a-http.d.ts.map +1 -0
  29. package/dist/core/a2a-http.js +217 -0
  30. package/dist/core/a2a-http.js.map +1 -0
  31. package/dist/core/a2a.d.ts +2 -0
  32. package/dist/core/a2a.d.ts.map +1 -1
  33. package/dist/core/a2a.js +6 -1
  34. package/dist/core/a2a.js.map +1 -1
  35. package/dist/core/agent.d.ts +1 -0
  36. package/dist/core/agent.d.ts.map +1 -1
  37. package/dist/core/agent.js +3 -0
  38. package/dist/core/agent.js.map +1 -1
  39. package/dist/core/gateway-registry.d.ts +116 -0
  40. package/dist/core/gateway-registry.d.ts.map +1 -0
  41. package/dist/core/gateway-registry.js +280 -0
  42. package/dist/core/gateway-registry.js.map +1 -0
  43. package/dist/core/model-recommender.d.ts +40 -0
  44. package/dist/core/model-recommender.d.ts.map +1 -0
  45. package/dist/core/model-recommender.js +186 -0
  46. package/dist/core/model-recommender.js.map +1 -0
  47. package/dist/core/priority-queue.d.ts +100 -0
  48. package/dist/core/priority-queue.d.ts.map +1 -0
  49. package/dist/core/priority-queue.js +181 -0
  50. package/dist/core/priority-queue.js.map +1 -0
  51. package/dist/core/runtime.d.ts.map +1 -1
  52. package/dist/core/runtime.js +192 -22
  53. package/dist/core/runtime.js.map +1 -1
  54. package/dist/deploy/index.js +56 -56
  55. package/dist/doctor.d.ts +1 -0
  56. package/dist/doctor.d.ts.map +1 -1
  57. package/dist/doctor.js +155 -10
  58. package/dist/doctor.js.map +1 -1
  59. package/dist/index.d.ts +10 -3
  60. package/dist/index.d.ts.map +1 -1
  61. package/dist/index.js +24 -13
  62. package/dist/index.js.map +1 -1
  63. package/dist/memory/deepbrain.d.ts +1 -1
  64. package/dist/memory/deepbrain.d.ts.map +1 -1
  65. package/dist/memory/deepbrain.js +95 -4
  66. package/dist/memory/deepbrain.js.map +1 -1
  67. package/dist/memory/evolve-engine.d.ts +113 -0
  68. package/dist/memory/evolve-engine.d.ts.map +1 -0
  69. package/dist/memory/evolve-engine.js +549 -0
  70. package/dist/memory/evolve-engine.js.map +1 -0
  71. package/dist/memory/index.d.ts +2 -0
  72. package/dist/memory/index.d.ts.map +1 -1
  73. package/dist/memory/index.js +3 -1
  74. package/dist/memory/index.js.map +1 -1
  75. package/dist/memory/sqlite-store.d.ts +40 -0
  76. package/dist/memory/sqlite-store.d.ts.map +1 -0
  77. package/dist/memory/sqlite-store.js +269 -0
  78. package/dist/memory/sqlite-store.js.map +1 -0
  79. package/dist/memory/user-profiler.d.ts +8 -0
  80. package/dist/memory/user-profiler.d.ts.map +1 -1
  81. package/dist/memory/user-profiler.js +89 -0
  82. package/dist/memory/user-profiler.js.map +1 -1
  83. package/dist/scheduler/cron-engine.d.ts.map +1 -1
  84. package/dist/scheduler/cron-engine.js +3 -36
  85. package/dist/scheduler/cron-engine.js.map +1 -1
  86. package/dist/scheduler/proactive.d.ts +62 -0
  87. package/dist/scheduler/proactive.d.ts.map +1 -0
  88. package/dist/scheduler/proactive.js +185 -0
  89. package/dist/scheduler/proactive.js.map +1 -0
  90. package/dist/skills/auto-learn.d.ts.map +1 -1
  91. package/dist/skills/auto-learn.js +65 -11
  92. package/dist/skills/auto-learn.js.map +1 -1
  93. package/dist/skills/builtin/index.d.ts.map +1 -1
  94. package/dist/skills/builtin/index.js +163 -30
  95. package/dist/skills/builtin/index.js.map +1 -1
  96. package/dist/skills/types.d.ts +1 -1
  97. package/dist/skills/types.d.ts.map +1 -1
  98. package/dist/skills/types.js +1 -0
  99. package/dist/skills/types.js.map +1 -1
  100. package/dist/studio/server.d.ts +1 -0
  101. package/dist/studio/server.d.ts.map +1 -1
  102. package/dist/studio/server.js +148 -17
  103. package/dist/studio/server.js.map +1 -1
  104. package/dist/studio-ui/index.html +867 -2630
  105. package/dist/ui/components.js +105 -105
  106. package/examples/README.md +22 -22
  107. package/examples/basic-agent.ts +90 -90
  108. package/examples/brain-integration.ts +71 -71
  109. package/examples/multi-channel.ts +74 -74
  110. package/install.ps1 +127 -127
  111. package/install.sh +154 -154
  112. package/models.json +164 -164
  113. package/package.json +5 -2
  114. package/scripts/install.ps1 +31 -31
  115. package/scripts/install.sh +40 -40
  116. package/templates/ecommerce-assistant/README.md +45 -45
  117. package/templates/ecommerce-assistant/oad.yaml +47 -47
  118. package/templates/tech-support/README.md +43 -43
  119. package/templates/tech-support/oad.yaml +45 -45
@@ -0,0 +1,280 @@
1
+ "use strict";
2
+ /**
3
+ * Tool Gateway — Remote managed tool provider pattern.
4
+ *
5
+ * Inspired by Hermes Agent v0.10's Tool Gateway feature.
6
+ * Allows agents to access remote tool services (web search, image gen, TTS,
7
+ * browser automation) through a unified gateway, removing the need for
8
+ * individual API keys per tool.
9
+ *
10
+ * Key features:
11
+ * - Subscription-based tool access (single API key → multiple tools)
12
+ * - Per-tool opt-in/opt-out via configuration
13
+ * - Auto-detection of gateway availability
14
+ * - Fallback to direct API keys when gateway unavailable
15
+ * - Usage tracking and quota enforcement
16
+ *
17
+ * Usage:
18
+ * const gw = new ToolGateway({ endpoint: 'https://tools.example.com', apiKey: '...' });
19
+ * await gw.connect();
20
+ * const result = await gw.invoke('web-search', { query: 'hello' });
21
+ */
22
+ Object.defineProperty(exports, "__esModule", { value: true });
23
+ exports.ToolGatewayRegistry = exports.ToolGateway = void 0;
24
+ const events_1 = require("events");
25
+ const logger_1 = require("./logger");
26
+ // ─── Tool Gateway ────────────────────────────────────────────
27
+ class ToolGateway extends events_1.EventEmitter {
28
+ config;
29
+ tools = new Map();
30
+ connected = false;
31
+ logger = new logger_1.Logger('tool-gateway');
32
+ invocationCount = 0;
33
+ constructor(config) {
34
+ super();
35
+ this.config = {
36
+ endpoint: config.endpoint.replace(/\/$/, ''),
37
+ apiKey: config.apiKey,
38
+ enabledTools: config.enabledTools ?? [],
39
+ timeout: config.timeout ?? 60_000,
40
+ preferGateway: config.preferGateway ?? true,
41
+ retry: {
42
+ maxRetries: config.retry?.maxRetries ?? 2,
43
+ backoffMs: config.retry?.backoffMs ?? 1000,
44
+ },
45
+ };
46
+ }
47
+ /** Connect to gateway and discover available tools */
48
+ async connect() {
49
+ try {
50
+ const res = await this.request('GET', '/tools');
51
+ const data = res;
52
+ this.tools.clear();
53
+ for (const tool of data.tools) {
54
+ // If enabledTools is specified, only include those
55
+ if (this.config.enabledTools.length === 0 ||
56
+ this.config.enabledTools.includes(tool.id)) {
57
+ this.tools.set(tool.id, tool);
58
+ }
59
+ }
60
+ this.connected = true;
61
+ this.logger.info('Connected to tool gateway', {
62
+ endpoint: this.config.endpoint,
63
+ tools: this.tools.size,
64
+ });
65
+ this.emit('connected', this.getStatus());
66
+ return {
67
+ connected: true,
68
+ endpoint: this.config.endpoint,
69
+ tools: Array.from(this.tools.values()),
70
+ subscription: data.subscription,
71
+ };
72
+ }
73
+ catch (err) {
74
+ this.connected = false;
75
+ this.logger.error('Failed to connect to tool gateway', {
76
+ error: err.message,
77
+ });
78
+ throw err;
79
+ }
80
+ }
81
+ /** Invoke a tool through the gateway */
82
+ async invoke(toolId, input) {
83
+ if (!this.connected) {
84
+ throw new Error('Tool gateway not connected. Call connect() first.');
85
+ }
86
+ const tool = this.tools.get(toolId);
87
+ if (!tool) {
88
+ return {
89
+ toolId,
90
+ requestId: this.generateRequestId(),
91
+ status: 'unavailable',
92
+ error: `Tool "${toolId}" not available on this gateway`,
93
+ durationMs: 0,
94
+ };
95
+ }
96
+ if (!tool.available) {
97
+ return {
98
+ toolId,
99
+ requestId: this.generateRequestId(),
100
+ status: 'unavailable',
101
+ error: `Tool "${toolId}" is currently unavailable`,
102
+ durationMs: 0,
103
+ };
104
+ }
105
+ const requestId = this.generateRequestId();
106
+ const start = Date.now();
107
+ try {
108
+ const result = await this.request('POST', '/invoke', {
109
+ toolId,
110
+ input,
111
+ requestId,
112
+ });
113
+ const durationMs = Date.now() - start;
114
+ this.invocationCount++;
115
+ const gatewayResult = {
116
+ toolId,
117
+ requestId,
118
+ status: 'success',
119
+ output: result.output,
120
+ durationMs,
121
+ quotaRemaining: result.quotaRemaining,
122
+ };
123
+ // Update quota info
124
+ if (gatewayResult.quotaRemaining !== undefined) {
125
+ tool.quotaRemaining = gatewayResult.quotaRemaining;
126
+ }
127
+ this.emit('invocation', gatewayResult);
128
+ return gatewayResult;
129
+ }
130
+ catch (err) {
131
+ const durationMs = Date.now() - start;
132
+ const message = err.message;
133
+ const status = message.includes('quota') ? 'quota_exceeded' : 'error';
134
+ const gatewayResult = {
135
+ toolId,
136
+ requestId,
137
+ status,
138
+ error: message,
139
+ durationMs,
140
+ };
141
+ this.emit('invocation:error', gatewayResult);
142
+ return gatewayResult;
143
+ }
144
+ }
145
+ /** Get a tool definition (for MCP/tool schema exposure) */
146
+ getTool(toolId) {
147
+ return this.tools.get(toolId);
148
+ }
149
+ /** List all available tools */
150
+ listTools() {
151
+ return Array.from(this.tools.values());
152
+ }
153
+ /** Get current status */
154
+ getStatus() {
155
+ return {
156
+ connected: this.connected,
157
+ endpoint: this.config.endpoint,
158
+ tools: Array.from(this.tools.values()),
159
+ };
160
+ }
161
+ /** Check if gateway should be preferred over direct API call */
162
+ shouldUseGateway(toolId) {
163
+ if (!this.connected)
164
+ return false;
165
+ if (!this.config.preferGateway)
166
+ return false;
167
+ const tool = this.tools.get(toolId);
168
+ if (!tool || !tool.available)
169
+ return false;
170
+ if (tool.quotaRemaining !== undefined && tool.quotaRemaining <= 0)
171
+ return false;
172
+ return true;
173
+ }
174
+ /** Disconnect from gateway */
175
+ disconnect() {
176
+ this.connected = false;
177
+ this.tools.clear();
178
+ this.emit('disconnected');
179
+ }
180
+ get isConnected() {
181
+ return this.connected;
182
+ }
183
+ get totalInvocations() {
184
+ return this.invocationCount;
185
+ }
186
+ // ─── Private helpers ─────────────────────────────────────────
187
+ async request(method, path, body) {
188
+ const url = `${this.config.endpoint}${path}`;
189
+ const controller = new AbortController();
190
+ const timer = setTimeout(() => controller.abort(), this.config.timeout);
191
+ let lastError;
192
+ const maxAttempts = 1 + (this.config.retry?.maxRetries ?? 0);
193
+ for (let attempt = 0; attempt < maxAttempts; attempt++) {
194
+ try {
195
+ const res = await fetch(url, {
196
+ method,
197
+ headers: {
198
+ 'Content-Type': 'application/json',
199
+ Authorization: `Bearer ${this.config.apiKey}`,
200
+ 'X-Client': 'opc-agent',
201
+ },
202
+ body: body ? JSON.stringify(body) : undefined,
203
+ signal: controller.signal,
204
+ });
205
+ clearTimeout(timer);
206
+ if (!res.ok) {
207
+ const errBody = await res.text().catch(() => '');
208
+ throw new Error(`Gateway ${res.status}: ${errBody || res.statusText}`);
209
+ }
210
+ return await res.json();
211
+ }
212
+ catch (err) {
213
+ lastError = err;
214
+ if (attempt < maxAttempts - 1) {
215
+ await new Promise(r => setTimeout(r, (this.config.retry?.backoffMs ?? 1000) * (attempt + 1)));
216
+ }
217
+ }
218
+ }
219
+ clearTimeout(timer);
220
+ throw lastError;
221
+ }
222
+ generateRequestId() {
223
+ return `gw_${++this.invocationCount}_${Date.now().toString(36)}`;
224
+ }
225
+ }
226
+ exports.ToolGateway = ToolGateway;
227
+ // ─── Tool Gateway Registry (multi-gateway support) ───────────
228
+ class ToolGatewayRegistry {
229
+ gateways = new Map();
230
+ toolToGateway = new Map();
231
+ logger = new logger_1.Logger('tool-gateway-registry');
232
+ /** Register a gateway */
233
+ register(name, gateway) {
234
+ this.gateways.set(name, gateway);
235
+ // Index tools → gateway
236
+ for (const tool of gateway.listTools()) {
237
+ this.toolToGateway.set(tool.id, name);
238
+ }
239
+ this.logger.info('Gateway registered', { name, tools: gateway.listTools().length });
240
+ }
241
+ /** Find which gateway provides a tool */
242
+ findGateway(toolId) {
243
+ const name = this.toolToGateway.get(toolId);
244
+ return name ? this.gateways.get(name) : undefined;
245
+ }
246
+ /** Invoke a tool, auto-routing to the right gateway */
247
+ async invoke(toolId, input) {
248
+ const gateway = this.findGateway(toolId);
249
+ if (!gateway) {
250
+ return {
251
+ toolId,
252
+ requestId: 'none',
253
+ status: 'unavailable',
254
+ error: `No gateway provides tool "${toolId}"`,
255
+ durationMs: 0,
256
+ };
257
+ }
258
+ return gateway.invoke(toolId, input);
259
+ }
260
+ /** List all tools across all gateways */
261
+ listAllTools() {
262
+ const result = [];
263
+ for (const [name, gw] of this.gateways) {
264
+ for (const tool of gw.listTools()) {
265
+ result.push({ ...tool, gateway: name });
266
+ }
267
+ }
268
+ return result;
269
+ }
270
+ /** Disconnect all gateways */
271
+ disconnectAll() {
272
+ for (const gw of this.gateways.values()) {
273
+ gw.disconnect();
274
+ }
275
+ this.gateways.clear();
276
+ this.toolToGateway.clear();
277
+ }
278
+ }
279
+ exports.ToolGatewayRegistry = ToolGatewayRegistry;
280
+ //# sourceMappingURL=gateway-registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gateway-registry.js","sourceRoot":"","sources":["../../src/core/gateway-registry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ export interface ModelRec {
2
+ name: string;
3
+ size: string;
4
+ minRAM: number;
5
+ desc: string;
6
+ descEn?: string;
7
+ tier: number;
8
+ lang?: string[];
9
+ useCase?: string[];
10
+ speed?: string;
11
+ recommended?: boolean;
12
+ }
13
+ interface SystemInfo {
14
+ totalRAM: number;
15
+ freeRAM: number;
16
+ cpuCount: number;
17
+ platform: string;
18
+ arch: string;
19
+ }
20
+ export declare function fetchModelList(): Promise<ModelRec[]>;
21
+ export declare function detectSystem(): SystemInfo;
22
+ export declare function recommendModels(models: ModelRec[], sys: SystemInfo, installedModels?: string[], opts?: {
23
+ useCase?: string;
24
+ lang?: string;
25
+ }): {
26
+ suitable: ModelRec[];
27
+ best: ModelRec;
28
+ installed: ModelRec[];
29
+ toDownload: ModelRec[];
30
+ };
31
+ /** Invalidate cache so next fetchModelList() re-downloads */
32
+ export declare function clearModelCache(): boolean;
33
+ /** Get cache info */
34
+ export declare function cacheInfo(): {
35
+ exists: boolean;
36
+ age?: string;
37
+ version?: string;
38
+ };
39
+ export {};
40
+ //# sourceMappingURL=model-recommender.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-recommender.d.ts","sourceRoot":"","sources":["../../src/core/model-recommender.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AASD,UAAU,UAAU;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;CACd;AA8CD,wBAAsB,cAAc,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC,CAsB1D;AAED,wBAAgB,YAAY,IAAI,UAAU,CAQzC;AAED,wBAAgB,eAAe,CAC7B,MAAM,EAAE,QAAQ,EAAE,EAClB,GAAG,EAAE,UAAU,EACf,eAAe,GAAE,MAAM,EAAO,EAC9B,IAAI,GAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAO,GAC7C;IACD,QAAQ,EAAE,QAAQ,EAAE,CAAC;IACrB,IAAI,EAAE,QAAQ,CAAC;IACf,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,UAAU,EAAE,QAAQ,EAAE,CAAC;CACxB,CA+BA;AAED,6DAA6D;AAC7D,wBAAgB,eAAe,IAAI,OAAO,CAMzC;AAED,qBAAqB;AACrB,wBAAgB,SAAS,IAAI;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,CAU/E"}
@@ -0,0 +1,186 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.fetchModelList = fetchModelList;
37
+ exports.detectSystem = detectSystem;
38
+ exports.recommendModels = recommendModels;
39
+ exports.clearModelCache = clearModelCache;
40
+ exports.cacheInfo = cacheInfo;
41
+ /**
42
+ * 智能模型推荐引擎
43
+ * - 远程模型列表 (GitHub) + 本地缓存 (24h) + 硬编码 fallback
44
+ * - 根据系统硬件自动推荐最适合的模型
45
+ */
46
+ const os = __importStar(require("os"));
47
+ const fs = __importStar(require("fs"));
48
+ const path = __importStar(require("path"));
49
+ const REMOTE_URL = 'https://raw.githubusercontent.com/Deepleaper/opc-agent/main/models.json';
50
+ const CACHE_FILE = '.opc-models-cache.json';
51
+ const CACHE_TTL = 24 * 60 * 60 * 1000; // 24 hours
52
+ // Hardcoded fallback (same as models.json, kept in sync)
53
+ const FALLBACK_MODELS = [
54
+ { name: 'qwen2.5:0.5b', size: '0.4GB', minRAM: 2, desc: '超轻量,适合低配机器', tier: 1 },
55
+ { name: 'qwen2.5:1.5b', size: '1.0GB', minRAM: 4, desc: '轻量但更智能', tier: 1 },
56
+ { name: 'qwen2.5:3b', size: '2.0GB', minRAM: 6, desc: '性价比最优', tier: 2 },
57
+ { name: 'llama3.2:3b', size: '2.0GB', minRAM: 6, desc: 'Meta 最新轻量模型', tier: 2 },
58
+ { name: 'phi3:mini', size: '2.3GB', minRAM: 6, desc: '微软高效小模型', tier: 2 },
59
+ { name: 'qwen2.5:7b', size: '4.7GB', minRAM: 8, desc: '推荐:中文最强 7B', tier: 3, recommended: true },
60
+ { name: 'llama3.1:8b', size: '4.7GB', minRAM: 8, desc: 'Meta 通用 8B', tier: 3 },
61
+ { name: 'mistral:7b', size: '4.1GB', minRAM: 8, desc: 'Mistral 经典 7B', tier: 3 },
62
+ { name: 'gemma2:9b', size: '5.4GB', minRAM: 10, desc: 'Google 高效 9B', tier: 3 },
63
+ { name: 'qwen2.5-coder:7b', size: '4.7GB', minRAM: 8, desc: '编程专用 7B', tier: 3 },
64
+ { name: 'qwen2.5:14b', size: '9.0GB', minRAM: 16, desc: '中文强力 14B', tier: 4 },
65
+ { name: 'deepseek-coder-v2:16b', size: '9.0GB', minRAM: 16, desc: '编程专用 16B', tier: 4 },
66
+ { name: 'qwen2.5:32b', size: '20GB', minRAM: 32, desc: '接近 GPT-4 水平', tier: 5, recommended: true },
67
+ { name: 'llama3.1:70b', size: '40GB', minRAM: 64, desc: '开源最强', tier: 6 },
68
+ ];
69
+ function getCachePath() {
70
+ return path.join(os.homedir(), CACHE_FILE);
71
+ }
72
+ function readCache() {
73
+ try {
74
+ const cachePath = getCachePath();
75
+ if (!fs.existsSync(cachePath))
76
+ return null;
77
+ const stat = fs.statSync(cachePath);
78
+ if (Date.now() - stat.mtimeMs > CACHE_TTL)
79
+ return null; // expired
80
+ const data = JSON.parse(fs.readFileSync(cachePath, 'utf-8'));
81
+ if (!data.models || !Array.isArray(data.models))
82
+ return null;
83
+ return data;
84
+ }
85
+ catch {
86
+ return null;
87
+ }
88
+ }
89
+ function writeCache(data) {
90
+ try {
91
+ fs.writeFileSync(getCachePath(), JSON.stringify(data, null, 2));
92
+ }
93
+ catch { /* best effort */ }
94
+ }
95
+ async function fetchModelList() {
96
+ // 1. Try cache
97
+ const cached = readCache();
98
+ if (cached)
99
+ return cached.models;
100
+ // 2. Try remote
101
+ try {
102
+ const controller = new AbortController();
103
+ const timeout = setTimeout(() => controller.abort(), 5000);
104
+ const res = await fetch(REMOTE_URL, { signal: controller.signal });
105
+ clearTimeout(timeout);
106
+ if (res.ok) {
107
+ const data = await res.json();
108
+ if (data.models && Array.isArray(data.models) && data.models.length > 0) {
109
+ writeCache(data);
110
+ return data.models;
111
+ }
112
+ }
113
+ }
114
+ catch { /* fallback */ }
115
+ // 3. Fallback
116
+ return FALLBACK_MODELS;
117
+ }
118
+ function detectSystem() {
119
+ return {
120
+ totalRAM: Math.round(os.totalmem() / (1024 ** 3)),
121
+ freeRAM: Math.round(os.freemem() / (1024 ** 3)),
122
+ cpuCount: os.cpus().length,
123
+ platform: os.platform(),
124
+ arch: os.arch(),
125
+ };
126
+ }
127
+ function recommendModels(models, sys, installedModels = [], opts = {}) {
128
+ const availableRAM = sys.freeRAM + 2; // +2GB tolerance
129
+ // Filter by hardware
130
+ let suitable = models.filter(m => m.minRAM <= availableRAM);
131
+ if (suitable.length === 0)
132
+ suitable = [models[0]]; // always have at least one
133
+ // Optional: filter by use case
134
+ if (opts.useCase) {
135
+ const filtered = suitable.filter(m => m.useCase?.includes(opts.useCase));
136
+ if (filtered.length > 0)
137
+ suitable = filtered;
138
+ }
139
+ // Optional: filter by language
140
+ if (opts.lang) {
141
+ const filtered = suitable.filter(m => m.lang?.includes(opts.lang));
142
+ if (filtered.length > 0)
143
+ suitable = filtered;
144
+ }
145
+ // Best = highest tier that fits, prefer 'recommended' flag
146
+ const recommended = suitable.filter(m => m.recommended);
147
+ const best = recommended.length > 0
148
+ ? recommended[recommended.length - 1]
149
+ : suitable[suitable.length - 1];
150
+ // Split installed vs to-download
151
+ const installedSet = new Set(installedModels);
152
+ const installed = suitable.filter(m => installedSet.has(m.name));
153
+ const toDownload = suitable.filter(m => !installedSet.has(m.name)).slice(-3); // top 3 recommendations
154
+ return { suitable, best, installed, toDownload };
155
+ }
156
+ /** Invalidate cache so next fetchModelList() re-downloads */
157
+ function clearModelCache() {
158
+ try {
159
+ const p = getCachePath();
160
+ if (fs.existsSync(p)) {
161
+ fs.unlinkSync(p);
162
+ return true;
163
+ }
164
+ return false;
165
+ }
166
+ catch {
167
+ return false;
168
+ }
169
+ }
170
+ /** Get cache info */
171
+ function cacheInfo() {
172
+ try {
173
+ const p = getCachePath();
174
+ if (!fs.existsSync(p))
175
+ return { exists: false };
176
+ const stat = fs.statSync(p);
177
+ const ageMs = Date.now() - stat.mtimeMs;
178
+ const hours = Math.round(ageMs / (60 * 60 * 1000));
179
+ const data = JSON.parse(fs.readFileSync(p, 'utf-8'));
180
+ return { exists: true, age: `${hours}h ago`, version: data.version };
181
+ }
182
+ catch {
183
+ return { exists: false };
184
+ }
185
+ }
186
+ //# sourceMappingURL=model-recommender.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-recommender.js","sourceRoot":"","sources":["../../src/core/model-recommender.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiFA,wCAsBC;AAED,oCAQC;AAED,0CAyCC;AAGD,0CAMC;AAGD,8BAUC;AAlLD;;;;GAIG;AACH,uCAAyB;AACzB,uCAAyB;AACzB,2CAA6B;AA8B7B,MAAM,UAAU,GAAG,yEAAyE,CAAC;AAC7F,MAAM,UAAU,GAAG,wBAAwB,CAAC;AAC5C,MAAM,SAAS,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,WAAW;AAElD,yDAAyD;AACzD,MAAM,eAAe,GAAe;IAClC,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,EAAE;IAC/E,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,EAAE;IAC3E,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE;IACxE,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,EAAE;IAC/E,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,EAAE;IACzE,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,EAAE,WAAW,EAAE,IAAI,EAAE;IAChG,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,EAAE;IAC9E,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,eAAe,EAAE,IAAI,EAAE,CAAC,EAAE;IAChF,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,CAAC,EAAE;IAC/E,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,EAAE;IAChF,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,EAAE;IAC7E,EAAE,IAAI,EAAE,uBAAuB,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,EAAE;IACvF,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,EAAE,WAAW,EAAE,IAAI,EAAE;IAClG,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE;CAC1E,CAAC;AAEF,SAAS,YAAY;IACnB,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,UAAU,CAAC,CAAC;AAC7C,CAAC;AAED,SAAS,SAAS;IAChB,IAAI,CAAC;QACH,MAAM,SAAS,GAAG,YAAY,EAAE,CAAC;QACjC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC;YAAE,OAAO,IAAI,CAAC;QAC3C,MAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;QACpC,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,OAAO,GAAG,SAAS;YAAE,OAAO,IAAI,CAAC,CAAC,UAAU;QAClE,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC;QAC7D,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC;YAAE,OAAO,IAAI,CAAC;QAC7D,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QAAC,OAAO,IAAI,CAAC;IAAC,CAAC;AAC1B,CAAC;AAED,SAAS,UAAU,CAAC,IAAe;IACjC,IAAI,CAAC;QACH,EAAE,CAAC,aAAa,CAAC,YAAY,EAAE,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAClE,CAAC;IAAC,MAAM,CAAC,CAAC,iBAAiB,CAAC,CAAC;AAC/B,CAAC;AAEM,KAAK,UAAU,cAAc;IAClC,eAAe;IACf,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;IAC3B,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC,MAAM,CAAC;IAEjC,gBAAgB;IAChB,IAAI,CAAC;QACH,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;QACzC,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,IAAI,CAAC,CAAC;QAC3D,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,UAAU,EAAE,EAAE,MAAM,EAAE,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC;QACnE,YAAY,CAAC,OAAO,CAAC,CAAC;QACtB,IAAI,GAAG,CAAC,EAAE,EAAE,CAAC;YACX,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAe,CAAC;YAC3C,IAAI,IAAI,CAAC,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACxE,UAAU,CAAC,IAAI,CAAC,CAAC;gBACjB,OAAO,IAAI,CAAC,MAAM,CAAC;YACrB,CAAC;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC,CAAC,cAAc,CAAC,CAAC;IAE1B,cAAc;IACd,OAAO,eAAe,CAAC;AACzB,CAAC;AAED,SAAgB,YAAY;IAC1B,OAAO;QACL,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC;QACjD,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC;QAC/C,QAAQ,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC,MAAM;QAC1B,QAAQ,EAAE,EAAE,CAAC,QAAQ,EAAE;QACvB,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE;KAChB,CAAC;AACJ,CAAC;AAED,SAAgB,eAAe,CAC7B,MAAkB,EAClB,GAAe,EACf,kBAA4B,EAAE,EAC9B,OAA4C,EAAE;IAO9C,MAAM,YAAY,GAAG,GAAG,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,iBAAiB;IAEvD,qBAAqB;IACrB,IAAI,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,IAAI,YAAY,CAAC,CAAC;IAC5D,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,QAAQ,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,2BAA2B;IAE9E,+BAA+B;IAC/B,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;QACjB,MAAM,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,QAAQ,CAAC,IAAI,CAAC,OAAQ,CAAC,CAAC,CAAC;QAC1E,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC;YAAE,QAAQ,GAAG,QAAQ,CAAC;IAC/C,CAAC;IAED,+BAA+B;IAC/B,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,MAAM,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC,IAAK,CAAC,CAAC,CAAC;QACpE,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC;YAAE,QAAQ,GAAG,QAAQ,CAAC;IAC/C,CAAC;IAED,2DAA2D;IAC3D,MAAM,WAAW,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;IACxD,MAAM,IAAI,GAAG,WAAW,CAAC,MAAM,GAAG,CAAC;QACjC,CAAC,CAAC,WAAW,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC;QACrC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAElC,iCAAiC;IACjC,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,eAAe,CAAC,CAAC;IAC9C,MAAM,SAAS,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IACjE,MAAM,UAAU,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,wBAAwB;IAEtG,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,CAAC;AACnD,CAAC;AAED,6DAA6D;AAC7D,SAAgB,eAAe;IAC7B,IAAI,CAAC;QACH,MAAM,CAAC,GAAG,YAAY,EAAE,CAAC;QACzB,IAAI,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;YAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;YAAC,OAAO,IAAI,CAAC;QAAC,CAAC;QACxD,OAAO,KAAK,CAAC;IACf,CAAC;IAAC,MAAM,CAAC;QAAC,OAAO,KAAK,CAAC;IAAC,CAAC;AAC3B,CAAC;AAED,qBAAqB;AACrB,SAAgB,SAAS;IACvB,IAAI,CAAC;QACH,MAAM,CAAC,GAAG,YAAY,EAAE,CAAC;QACzB,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;YAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;QAChD,MAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;QAC5B,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC;QACxC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC;QACnD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;QACrD,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,KAAK,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC;IACvE,CAAC;IAAC,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;IAAC,CAAC;AACvC,CAAC"}
@@ -0,0 +1,100 @@
1
+ /**
2
+ * Priority Queue / Fast Mode — Route requests through priority tiers
3
+ * for lower latency on supported providers.
4
+ *
5
+ * Inspired by Hermes Agent's /fast mode. Provides a priority-aware request
6
+ * queue that separates normal and fast-mode requests, ensuring fast-mode
7
+ * requests are processed first and routed to provider priority endpoints.
8
+ *
9
+ * Usage:
10
+ * const pq = new PriorityQueue();
11
+ * pq.enqueue({ id: 'req1', priority: 'fast', provider: 'openai', ... });
12
+ * const next = pq.dequeue(); // Always returns highest priority first
13
+ */
14
+ import { EventEmitter } from 'events';
15
+ export type PriorityLevel = 'fast' | 'normal' | 'batch';
16
+ export interface PriorityRequest {
17
+ id: string;
18
+ priority: PriorityLevel;
19
+ provider: string;
20
+ model: string;
21
+ payload: unknown;
22
+ enqueuedAt: number;
23
+ metadata?: Record<string, unknown>;
24
+ }
25
+ export interface PriorityConfig {
26
+ /** Maximum concurrent fast-mode requests per provider */
27
+ maxConcurrentFast?: number;
28
+ /** Maximum concurrent normal requests per provider */
29
+ maxConcurrentNormal?: number;
30
+ /** Timeout for fast-mode requests before fallback (ms, default 30s) */
31
+ fastTimeout?: number;
32
+ /** Providers that support priority routing */
33
+ supportedProviders?: string[];
34
+ }
35
+ export interface ProviderPriorityEndpoint {
36
+ provider: string;
37
+ priorityUrl?: string;
38
+ priorityHeader?: {
39
+ key: string;
40
+ value: string;
41
+ };
42
+ priorityParam?: {
43
+ key: string;
44
+ value: string;
45
+ };
46
+ }
47
+ export declare class PriorityQueue extends EventEmitter {
48
+ private queues;
49
+ private activeCounts;
50
+ private config;
51
+ private endpoints;
52
+ constructor(config?: PriorityConfig);
53
+ /** Register a custom priority endpoint for a provider */
54
+ registerEndpoint(endpoint: ProviderPriorityEndpoint): void;
55
+ /** Check if a provider supports priority routing */
56
+ supportsPriority(provider: string): boolean;
57
+ /** Get priority endpoint configuration for a provider */
58
+ getEndpoint(provider: string): ProviderPriorityEndpoint | undefined;
59
+ /** Enqueue a request */
60
+ enqueue(request: PriorityRequest): void;
61
+ /** Dequeue the next highest-priority request that can run */
62
+ dequeue(): PriorityRequest | undefined;
63
+ /** Mark a request as completed, freeing a concurrency slot */
64
+ complete(provider: string, priority: PriorityLevel): void;
65
+ /** Get queue lengths */
66
+ getStats(): {
67
+ fast: number;
68
+ normal: number;
69
+ batch: number;
70
+ total: number;
71
+ active: Record<string, {
72
+ fast: number;
73
+ normal: number;
74
+ batch: number;
75
+ }>;
76
+ };
77
+ /** Drain all requests (for shutdown) */
78
+ drain(): PriorityRequest[];
79
+ /** Determine effective priority for a request (auto-upgrade/downgrade) */
80
+ static resolvePriority(requested: PriorityLevel, provider: string, supportedProviders: string[]): PriorityLevel;
81
+ private canRun;
82
+ private incrementActive;
83
+ }
84
+ /**
85
+ * Tracks per-session fast mode toggle (like /fast command).
86
+ */
87
+ export declare class FastModeManager {
88
+ private sessions;
89
+ /** Toggle fast mode for a session, returns new state */
90
+ toggle(sessionId: string): boolean;
91
+ /** Set fast mode explicitly */
92
+ set(sessionId: string, enabled: boolean): void;
93
+ /** Check if session has fast mode enabled */
94
+ isEnabled(sessionId: string): boolean;
95
+ /** Get priority level for a session */
96
+ getPriority(sessionId: string): PriorityLevel;
97
+ /** Clear all state */
98
+ reset(): void;
99
+ }
100
+ //# sourceMappingURL=priority-queue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"priority-queue.d.ts","sourceRoot":"","sources":["../../src/core/priority-queue.ts"],"names":[],"mappings":"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"}