micro-models-agent 0.10.0 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/commands.js +46 -0
- package/dist/cli/repl.js +94 -1
- package/dist/i18n/en.json +13 -0
- package/dist/i18n/ru.json +11 -0
- package/dist/llm/openai-compat.js +26 -0
- package/package.json +1 -1
package/dist/cli/commands.js
CHANGED
|
@@ -78,6 +78,35 @@ export function createProgram() {
|
|
|
78
78
|
.action(async () => {
|
|
79
79
|
const { config } = await bootstrap();
|
|
80
80
|
console.log(t("cli.current_model"), config.model);
|
|
81
|
+
// Fetch available models from provider
|
|
82
|
+
const { OpenAICompatProvider } = await import("../llm/openai-compat");
|
|
83
|
+
const provider = new OpenAICompatProvider({
|
|
84
|
+
model: config.model,
|
|
85
|
+
baseUrl: config.provider.baseUrl,
|
|
86
|
+
apiKey: config.provider.apiKey,
|
|
87
|
+
contextWindow: config.contextWindow,
|
|
88
|
+
});
|
|
89
|
+
const spinner = (await import("../ui/spinner")).Spinner;
|
|
90
|
+
const s = new spinner();
|
|
91
|
+
s.start(t("cli.fetching_models"));
|
|
92
|
+
try {
|
|
93
|
+
const models = await provider.listModels();
|
|
94
|
+
s.stop();
|
|
95
|
+
if (models.length > 0) {
|
|
96
|
+
console.log(t("cli.available_models"));
|
|
97
|
+
for (const m of models) {
|
|
98
|
+
const marker = m === config.model ? "* " : " ";
|
|
99
|
+
console.log(` ${marker}${m}`);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
console.log(t("cli.no_models_found"));
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
catch (err) {
|
|
107
|
+
s.stop();
|
|
108
|
+
console.log(t("cli.model_fetch_failed", { error: String(err) }));
|
|
109
|
+
}
|
|
81
110
|
console.log(t("cli.model_hint"));
|
|
82
111
|
});
|
|
83
112
|
model
|
|
@@ -91,6 +120,23 @@ export function createProgram() {
|
|
|
91
120
|
saveConfig(config, configPath);
|
|
92
121
|
console.log(t("cli.model_set", { name }));
|
|
93
122
|
});
|
|
123
|
+
// Context window command
|
|
124
|
+
program
|
|
125
|
+
.command("context")
|
|
126
|
+
.description(t("cli.manage_context"))
|
|
127
|
+
.argument("<size>", "Context window size in tokens")
|
|
128
|
+
.action(async (size) => {
|
|
129
|
+
const configPath = join(homedir(), ".mma", "config.json");
|
|
130
|
+
const { config } = await bootstrap();
|
|
131
|
+
const contextWindow = parseInt(size, 10);
|
|
132
|
+
if (isNaN(contextWindow) || contextWindow < 1024) {
|
|
133
|
+
console.log(t("cli.invalid_context_size"));
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
config.contextWindow = contextWindow;
|
|
137
|
+
saveConfig(config, configPath);
|
|
138
|
+
console.log(t("cli.context_set", { size: contextWindow }));
|
|
139
|
+
});
|
|
94
140
|
const provider = program
|
|
95
141
|
.command("provider")
|
|
96
142
|
.description(t("cli.manage_providers"));
|
package/dist/cli/repl.js
CHANGED
|
@@ -20,6 +20,8 @@ const COMMAND_GROUPS = {
|
|
|
20
20
|
reasoning: "agent",
|
|
21
21
|
provider: "agent",
|
|
22
22
|
model: "agent",
|
|
23
|
+
context: "agent",
|
|
24
|
+
reload: "agent",
|
|
23
25
|
wizard: "agent",
|
|
24
26
|
sessions: "session",
|
|
25
27
|
new: "session",
|
|
@@ -235,10 +237,40 @@ export class Repl {
|
|
|
235
237
|
name: "model",
|
|
236
238
|
description: t("repl.model_list"),
|
|
237
239
|
usage: t("repl.model_usage"),
|
|
238
|
-
action: (args) => {
|
|
240
|
+
action: async (args) => {
|
|
239
241
|
const subcmd = args[0];
|
|
240
242
|
if (!subcmd || subcmd === "list") {
|
|
241
243
|
console.log(`${t("repl.model_current")} ${this.config.model}`);
|
|
244
|
+
// Fetch available models from provider
|
|
245
|
+
const { OpenAICompatProvider } = await import("../llm/openai-compat");
|
|
246
|
+
const provider = new OpenAICompatProvider({
|
|
247
|
+
model: this.config.model,
|
|
248
|
+
baseUrl: this.config.provider.baseUrl,
|
|
249
|
+
apiKey: this.config.provider.apiKey,
|
|
250
|
+
contextWindow: this.config.contextWindow,
|
|
251
|
+
});
|
|
252
|
+
const { Spinner } = await import("../ui/spinner");
|
|
253
|
+
const s = new Spinner();
|
|
254
|
+
s.start(t("cli.fetching_models"));
|
|
255
|
+
try {
|
|
256
|
+
const models = await provider.listModels();
|
|
257
|
+
s.stop();
|
|
258
|
+
if (models.length > 0) {
|
|
259
|
+
console.log(t("cli.available_models"));
|
|
260
|
+
for (const m of models) {
|
|
261
|
+
const marker = m === this.config.model ? pc.green("* ") : " ";
|
|
262
|
+
console.log(` ${marker}${m}`);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
else {
|
|
266
|
+
console.log(t("cli.no_models_found"));
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
catch (err) {
|
|
270
|
+
s.stop();
|
|
271
|
+
console.log(t("cli.model_fetch_failed", { error: String(err) }));
|
|
272
|
+
}
|
|
273
|
+
console.log(t("cli.model_hint"));
|
|
242
274
|
return;
|
|
243
275
|
}
|
|
244
276
|
if (subcmd === "use") {
|
|
@@ -256,6 +288,67 @@ export class Repl {
|
|
|
256
288
|
console.log(t("repl.model_usage"));
|
|
257
289
|
},
|
|
258
290
|
});
|
|
291
|
+
this.registerCommand({
|
|
292
|
+
name: "context",
|
|
293
|
+
description: t("cli.manage_context"),
|
|
294
|
+
usage: "/context <size>",
|
|
295
|
+
action: (args) => {
|
|
296
|
+
if (args.length === 0) {
|
|
297
|
+
console.log(`/context ${t("repl.context")} ${this.config.contextWindow}`);
|
|
298
|
+
console.log(t("repl.model_usage").replace("/model", "/context"));
|
|
299
|
+
return;
|
|
300
|
+
}
|
|
301
|
+
const size = parseInt(args[0], 10);
|
|
302
|
+
if (isNaN(size) || size < 1024) {
|
|
303
|
+
console.log(t("cli.invalid_context_size"));
|
|
304
|
+
return;
|
|
305
|
+
}
|
|
306
|
+
this.config.contextWindow = size;
|
|
307
|
+
const configPath = join(homedir(), ".mma", "config.json");
|
|
308
|
+
saveConfig(this.config, configPath);
|
|
309
|
+
console.log(pc.green(t("cli.context_set", { size })));
|
|
310
|
+
},
|
|
311
|
+
});
|
|
312
|
+
this.registerCommand({
|
|
313
|
+
name: "reload",
|
|
314
|
+
description: t("repl.reload"),
|
|
315
|
+
usage: t("repl.reload_usage"),
|
|
316
|
+
action: async () => {
|
|
317
|
+
console.log(pc.yellow(t("repl.reloading")));
|
|
318
|
+
// Save current session if auto-save enabled
|
|
319
|
+
if (this.sessionManager && this.config.session.autoSave) {
|
|
320
|
+
const active = this.sessionManager.getActiveMeta();
|
|
321
|
+
if (active) {
|
|
322
|
+
// Session is already auto-saved on each message
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
// Shutdown current agent
|
|
326
|
+
this.agent.shutdown();
|
|
327
|
+
// Reload config from disk
|
|
328
|
+
const { loadConfig } = await import("../config/config");
|
|
329
|
+
const { homedir } = await import("os");
|
|
330
|
+
const { join } = await import("path");
|
|
331
|
+
const configDir = join(homedir(), ".mma");
|
|
332
|
+
const projectConfigPath = join(process.cwd(), ".mmrc");
|
|
333
|
+
const freshConfig = loadConfig({ configDir, projectConfigPath });
|
|
334
|
+
// Update config reference
|
|
335
|
+
Object.assign(this.config, freshConfig);
|
|
336
|
+
// Recreate agent with new config (re-bootstrap)
|
|
337
|
+
const { bootstrap } = await import("../core/bootstrap");
|
|
338
|
+
const result = await bootstrap(configDir, process.cwd(), this.noAgentsMd, false);
|
|
339
|
+
// Replace agent and related components
|
|
340
|
+
this.agent = result.agent;
|
|
341
|
+
this.sessionManager = result.sessionManager;
|
|
342
|
+
this.skillsModule = result.skillsModule;
|
|
343
|
+
this.pluginManager = result.pluginManager;
|
|
344
|
+
// Update completer with new session/skill data
|
|
345
|
+
this.setupCompleter();
|
|
346
|
+
console.log(pc.green(t("repl.reloaded")));
|
|
347
|
+
console.log(`${t("repl.model")} ${this.config.model}`);
|
|
348
|
+
console.log(`${t("repl.context")} ${this.config.contextWindow}`);
|
|
349
|
+
console.log(`${t("repl.provider")} ${this.config.provider.type} @ ${this.config.provider.baseUrl}`);
|
|
350
|
+
},
|
|
351
|
+
});
|
|
259
352
|
}
|
|
260
353
|
registerSessionCommands() {
|
|
261
354
|
if (!this.sessionManager)
|
package/dist/i18n/en.json
CHANGED
|
@@ -178,6 +178,19 @@
|
|
|
178
178
|
"cli.list_models": "List available models",
|
|
179
179
|
"cli.current_model": "Current model:",
|
|
180
180
|
"cli.model_hint": "(Use /model use <name> to change)",
|
|
181
|
+
"cli.model_fetch_failed": "Failed to fetch models: {error}",
|
|
182
|
+
"cli.available_models": "Available models:",
|
|
183
|
+
"cli.no_models_found": "No models found from provider",
|
|
184
|
+
"cli.fetching_models": "Fetching model list...",
|
|
185
|
+
"cli.manage_context": "Manage context window",
|
|
186
|
+
"cli.invalid_context_size": "Invalid context size. Must be a number >= 1024",
|
|
187
|
+
"cli.context_set": "Context window set to: {size} tokens",
|
|
188
|
+
"cli.manage_context": "Manage context window",
|
|
189
|
+
"cli.invalid_context_size": "Invalid context size. Must be a number >= 1024",
|
|
190
|
+
"repl.reload": "Reload agent with current config",
|
|
191
|
+
"repl.reload_usage": "Usage: /reload",
|
|
192
|
+
"repl.reloading": "Reloading agent...",
|
|
193
|
+
"repl.reloaded": "Agent reloaded",
|
|
181
194
|
"cli.set_model": "Set default model",
|
|
182
195
|
"cli.model_set": "Model set to: {name}",
|
|
183
196
|
"cli.manage_providers": "Manage providers",
|
package/dist/i18n/ru.json
CHANGED
|
@@ -178,6 +178,13 @@
|
|
|
178
178
|
"cli.list_models": "Список доступных моделей",
|
|
179
179
|
"cli.current_model": "Текущая модель:",
|
|
180
180
|
"cli.model_hint": "(Используйте /model use <имя> для смены)",
|
|
181
|
+
"cli.model_fetch_failed": "Не удалось получить модели: {error}",
|
|
182
|
+
"cli.available_models": "Доступные модели:",
|
|
183
|
+
"cli.no_models_found": "Модели не найдены у провайдера",
|
|
184
|
+
"cli.fetching_models": "Загрузка списка моделей...",
|
|
185
|
+
"cli.manage_context": "Управление контекстным окном",
|
|
186
|
+
"cli.invalid_context_size": "Некорректный размер контекста. Должно быть число >= 1024",
|
|
187
|
+
"cli.context_set": "Контекстное окно установлено: {size} токенов",
|
|
181
188
|
"cli.set_model": "Установить модель по умолчанию",
|
|
182
189
|
"cli.model_set": "Модель установлена: {name}",
|
|
183
190
|
"cli.manage_providers": "Управление провайдерами",
|
|
@@ -310,6 +317,10 @@
|
|
|
310
317
|
"repl.model_current": "Текущая модель",
|
|
311
318
|
"repl.model_set": "Модель установлена: {name}",
|
|
312
319
|
"repl.model_usage": "Использование: /model list | /model use <имя>",
|
|
320
|
+
"repl.reload": "Перезагрузить агента с текущим конфигом",
|
|
321
|
+
"repl.reload_usage": "Использование: /reload",
|
|
322
|
+
"repl.reloading": "Перезагрузка агента...",
|
|
323
|
+
"repl.reloaded": "Агент перезагружен",
|
|
313
324
|
"repl.group.general": "Общее",
|
|
314
325
|
"repl.group.agent": "Агент",
|
|
315
326
|
"repl.group.session": "Сессии",
|
|
@@ -244,6 +244,32 @@ export class OpenAICompatProvider {
|
|
|
244
244
|
countTokens(text) {
|
|
245
245
|
return this.tokenCounter.count(text);
|
|
246
246
|
}
|
|
247
|
+
async listModels() {
|
|
248
|
+
try {
|
|
249
|
+
const url = `${this.config.baseUrl.replace(/\/+$/, "")}/models`;
|
|
250
|
+
const headers = {
|
|
251
|
+
"Content-Type": "application/json",
|
|
252
|
+
};
|
|
253
|
+
if (this.config.apiKey && this.config.apiKey !== "not-needed") {
|
|
254
|
+
headers["Authorization"] = `Bearer ${this.config.apiKey}`;
|
|
255
|
+
}
|
|
256
|
+
const response = await fetch(url, {
|
|
257
|
+
method: "GET",
|
|
258
|
+
headers,
|
|
259
|
+
});
|
|
260
|
+
if (!response.ok) {
|
|
261
|
+
return [];
|
|
262
|
+
}
|
|
263
|
+
const data = (await response.json());
|
|
264
|
+
const models = (data.data || data || [])
|
|
265
|
+
.map((m) => m.id || m.name || m.model || "")
|
|
266
|
+
.filter(Boolean);
|
|
267
|
+
return models;
|
|
268
|
+
}
|
|
269
|
+
catch {
|
|
270
|
+
return [];
|
|
271
|
+
}
|
|
272
|
+
}
|
|
247
273
|
async fetchWithRetry(url, init) {
|
|
248
274
|
const { maxRetries, baseDelay, maxDelay } = this.retryConfig;
|
|
249
275
|
let lastError = null;
|