micro-models-agent 0.10.0 → 0.11.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.
@@ -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
@@ -235,10 +235,40 @@ export class Repl {
235
235
  name: "model",
236
236
  description: t("repl.model_list"),
237
237
  usage: t("repl.model_usage"),
238
- action: (args) => {
238
+ action: async (args) => {
239
239
  const subcmd = args[0];
240
240
  if (!subcmd || subcmd === "list") {
241
241
  console.log(`${t("repl.model_current")} ${this.config.model}`);
242
+ // Fetch available models from provider
243
+ const { OpenAICompatProvider } = await import("../llm/openai-compat");
244
+ const provider = new OpenAICompatProvider({
245
+ model: this.config.model,
246
+ baseUrl: this.config.provider.baseUrl,
247
+ apiKey: this.config.provider.apiKey,
248
+ contextWindow: this.config.contextWindow,
249
+ });
250
+ const { Spinner } = await import("../ui/spinner");
251
+ const s = new Spinner();
252
+ s.start(t("cli.fetching_models"));
253
+ try {
254
+ const models = await provider.listModels();
255
+ s.stop();
256
+ if (models.length > 0) {
257
+ console.log(t("cli.available_models"));
258
+ for (const m of models) {
259
+ const marker = m === this.config.model ? pc.green("* ") : " ";
260
+ console.log(` ${marker}${m}`);
261
+ }
262
+ }
263
+ else {
264
+ console.log(t("cli.no_models_found"));
265
+ }
266
+ }
267
+ catch (err) {
268
+ s.stop();
269
+ console.log(t("cli.model_fetch_failed", { error: String(err) }));
270
+ }
271
+ console.log(t("cli.model_hint"));
242
272
  return;
243
273
  }
244
274
  if (subcmd === "use") {
@@ -256,6 +286,27 @@ export class Repl {
256
286
  console.log(t("repl.model_usage"));
257
287
  },
258
288
  });
289
+ this.registerCommand({
290
+ name: "context",
291
+ description: t("cli.manage_context"),
292
+ usage: "/context <size>",
293
+ action: (args) => {
294
+ if (args.length === 0) {
295
+ console.log(`/context ${t("repl.context")} ${this.config.contextWindow}`);
296
+ console.log(t("repl.model_usage").replace("/model", "/context"));
297
+ return;
298
+ }
299
+ const size = parseInt(args[0], 10);
300
+ if (isNaN(size) || size < 1024) {
301
+ console.log(t("cli.invalid_context_size"));
302
+ return;
303
+ }
304
+ this.config.contextWindow = size;
305
+ const configPath = join(homedir(), ".mma", "config.json");
306
+ saveConfig(this.config, configPath);
307
+ console.log(pc.green(t("cli.context_set", { size })));
308
+ },
309
+ });
259
310
  }
260
311
  registerSessionCommands() {
261
312
  if (!this.sessionManager)
package/dist/i18n/en.json CHANGED
@@ -178,6 +178,15 @@
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",
181
190
  "cli.set_model": "Set default model",
182
191
  "cli.model_set": "Model set to: {name}",
183
192
  "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": "Управление провайдерами",
@@ -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;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "micro-models-agent",
3
- "version": "0.10.0",
3
+ "version": "0.11.0",
4
4
  "description": "Micro Models Agent (MMA) — LLM agent harness for small models (Qwen3.5-9B, 32K-64K context)",
5
5
  "type": "module",
6
6
  "bin": {