@massa-ai/opencode-plugin 1.57.0 → 1.59.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.
@@ -399,11 +399,129 @@ function configDir(app) {
399
399
  }
400
400
  var init_xdg = () => {};
401
401
 
402
+ // ../../packages/shared/dist/config/embedding-dimensions.js
403
+ function knownEmbeddingDimensions(model) {
404
+ if (!model)
405
+ return;
406
+ return KNOWN_EMBEDDING_DIMENSIONS[model.trim()];
407
+ }
408
+ var KNOWN_EMBEDDING_DIMENSIONS;
409
+ var init_embedding_dimensions = __esm(() => {
410
+ KNOWN_EMBEDDING_DIMENSIONS = {
411
+ "qwen3-embedding:8b": 4096,
412
+ "qwen3-embedding:4b": 2560,
413
+ "qwen3-embedding:0.6b": 1024,
414
+ "bge-m3": 1024
415
+ };
416
+ });
417
+
418
+ // ../../packages/shared/dist/config/inference-providers.js
419
+ function parseOllamaModelList(body) {
420
+ if (typeof body !== "object" || body === null)
421
+ return null;
422
+ const models = body.models;
423
+ if (!Array.isArray(models))
424
+ return null;
425
+ return models.map((entry) => entry.name).filter((name) => typeof name === "string");
426
+ }
427
+ function parseLmStudioModelList(body) {
428
+ if (typeof body !== "object" || body === null)
429
+ return null;
430
+ const data = body.data;
431
+ if (!Array.isArray(data))
432
+ return null;
433
+ return data.map((entry) => entry.id).filter((id) => typeof id === "string");
434
+ }
435
+ function deriveInferenceBaseUrls(providerId, explicitBaseUrl) {
436
+ const spec = INFERENCE_PROVIDERS[providerId];
437
+ if (!explicitBaseUrl) {
438
+ return {
439
+ embeddingBaseUrl: spec.defaultEmbeddingBaseUrl,
440
+ llmBaseUrl: spec.defaultLlmBaseUrl
441
+ };
442
+ }
443
+ let end = explicitBaseUrl.length;
444
+ while (end > 0 && explicitBaseUrl.charCodeAt(end - 1) === SLASH)
445
+ end--;
446
+ const base = explicitBaseUrl.slice(0, end);
447
+ const suffix = spec.defaultLlmBaseUrl.startsWith(spec.defaultEmbeddingBaseUrl) ? spec.defaultLlmBaseUrl.slice(spec.defaultEmbeddingBaseUrl.length) : "";
448
+ return {
449
+ embeddingBaseUrl: base,
450
+ llmBaseUrl: `${base}${suffix}`
451
+ };
452
+ }
453
+ var LOCAL_INFERENCE_IDS, INFERENCE_ROLE_DEFAULTS, INFERENCE_PROVIDERS, SLASH = 47;
454
+ var init_inference_providers = __esm(() => {
455
+ init_embedding_dimensions();
456
+ LOCAL_INFERENCE_IDS = ["ollama", "lmstudio"];
457
+ INFERENCE_ROLE_DEFAULTS = {
458
+ embedding: { contextWindow: 8192 },
459
+ instruct: { contextWindow: 16384, temperature: 0.2 },
460
+ coding: { contextWindow: 32768, temperature: 0 }
461
+ };
462
+ INFERENCE_PROVIDERS = {
463
+ ollama: {
464
+ id: "ollama",
465
+ defaultEmbeddingBaseUrl: "http://localhost:11434",
466
+ defaultLlmBaseUrl: "http://localhost:11434/v1",
467
+ envNames: {
468
+ model: "OLLAMA_EMBEDDING_MODEL",
469
+ baseUrl: "OLLAMA_BASE_URL",
470
+ dimensions: "OLLAMA_EMBEDDING_DIMENSIONS"
471
+ },
472
+ knownDimensions: KNOWN_EMBEDDING_DIMENSIONS,
473
+ defaultModels: {
474
+ embedding: "qwen3-embedding:0.6b",
475
+ instruct: "qwen3-vl:8b",
476
+ coding: "qwen2.5-coder:7b"
477
+ },
478
+ appliesContextPerRequest: true,
479
+ embedBatchSize: 64,
480
+ supportsOllamaVersionProbe: true,
481
+ injectsDisableThink: true,
482
+ requiresChatCompletionsApi: false,
483
+ parseModelList: parseOllamaModelList
484
+ },
485
+ lmstudio: {
486
+ id: "lmstudio",
487
+ defaultEmbeddingBaseUrl: "http://localhost:1234/v1",
488
+ defaultLlmBaseUrl: "http://localhost:1234/v1",
489
+ envNames: {
490
+ model: "LMSTUDIO_EMBEDDING_MODEL",
491
+ baseUrl: "LMSTUDIO_BASE_URL",
492
+ dimensions: "LMSTUDIO_EMBEDDING_DIMENSIONS"
493
+ },
494
+ knownDimensions: {
495
+ "text-embedding-nomic-embed-text-v1.5": 768,
496
+ "text-embedding-qwen3-embedding-0.6b": 1024
497
+ },
498
+ defaultModels: {
499
+ embedding: "text-embedding-qwen3-embedding-0.6b",
500
+ instruct: "qwen3-vl-8b-instruct",
501
+ coding: "qwen2.5-coder-7b-instruct"
502
+ },
503
+ appliesContextPerRequest: false,
504
+ embedBatchSize: 64,
505
+ supportsOllamaVersionProbe: false,
506
+ injectsDisableThink: false,
507
+ requiresChatCompletionsApi: true,
508
+ parseModelList: parseLmStudioModelList
509
+ }
510
+ };
511
+ });
512
+
402
513
  // ../../packages/shared/dist/config/massa-ai-config.js
403
514
  import path2 from "path";
404
- var SCHEDULER_JOB_KINDS, MAX_MATCH_WORK = 1e5, MAX_IGNORE_PATTERNS = 1024, DEFAULT_CAPTURE_POLICY, DEFAULT_SCHEDULER_CONFIG, defaultMassaAiConfig;
515
+ var API_PROVIDER_IDS, EMBEDDING_PROVIDER_IDS, SCHEDULER_JOB_KINDS, MAX_MATCH_WORK = 1e5, MAX_IGNORE_PATTERNS = 1024, DEFAULT_CAPTURE_POLICY, DEFAULT_SCHEDULER_CONFIG, defaultMassaAiConfig;
405
516
  var init_massa_ai_config = __esm(() => {
406
517
  init_xdg();
518
+ init_inference_providers();
519
+ init_embedding_dimensions();
520
+ API_PROVIDER_IDS = ["mistral", "openai", "google", "cohere"];
521
+ EMBEDDING_PROVIDER_IDS = [
522
+ ...LOCAL_INFERENCE_IDS,
523
+ ...API_PROVIDER_IDS
524
+ ];
407
525
  SCHEDULER_JOB_KINDS = [
408
526
  "memory-consolidation",
409
527
  "decay-sweep",
@@ -465,9 +583,9 @@ var init_massa_ai_config = __esm(() => {
465
583
  },
466
584
  embedding: {
467
585
  provider: "ollama",
468
- model: "qwen3-embedding:4b",
586
+ model: INFERENCE_PROVIDERS.ollama.defaultModels.embedding,
469
587
  baseURL: "http://localhost:11434",
470
- dimensions: 2560
588
+ dimensions: knownEmbeddingDimensions(INFERENCE_PROVIDERS.ollama.defaultModels.embedding) ?? 768
471
589
  },
472
590
  compression: {
473
591
  defaultStrategy: "code_structure",
@@ -506,12 +624,15 @@ var init_massa_ai_config = __esm(() => {
506
624
  enabled: false,
507
625
  baseUrl: "http://localhost:11434/v1",
508
626
  apiKey: "ollama",
509
- model: "qwen2.5:7b-instruct",
510
- codeModel: "qwen2.5-coder:7b",
627
+ model: INFERENCE_PROVIDERS.ollama.defaultModels.instruct,
628
+ codeModel: INFERENCE_PROVIDERS.ollama.defaultModels.coding,
511
629
  temperature: 0.2,
512
630
  maxOutputTokens: 8000,
513
631
  timeoutMs: 90000,
514
- disableThink: true
632
+ disableThink: true,
633
+ contextWindow: INFERENCE_ROLE_DEFAULTS.instruct.contextWindow,
634
+ codeContextWindow: INFERENCE_ROLE_DEFAULTS.coding.contextWindow,
635
+ codeTemperature: INFERENCE_ROLE_DEFAULTS.coding.temperature
515
636
  },
516
637
  memory: {
517
638
  decay: {
@@ -672,11 +793,12 @@ function loadConfig() {
672
793
  try {
673
794
  const content = fs.readFileSync(CONFIG_FILE, "utf-8");
674
795
  const userConfig = JSON.parse(content);
796
+ const embeddingBase = userConfig.embedding?.provider && userConfig.embedding.provider !== defaultMassaAiConfig.embedding.provider ? {} : defaultMassaAiConfig.embedding;
675
797
  return {
676
798
  ...defaultMassaAiConfig,
677
799
  ...userConfig,
678
800
  database: { ...defaultMassaAiConfig.database, ...userConfig.database },
679
- embedding: { ...defaultMassaAiConfig.embedding, ...userConfig.embedding },
801
+ embedding: { ...embeddingBase, ...userConfig.embedding },
680
802
  compression: { ...defaultMassaAiConfig.compression, ...userConfig.compression },
681
803
  cache: { ...defaultMassaAiConfig.cache, ...userConfig.cache },
682
804
  logging: { ...defaultMassaAiConfig.logging, ...userConfig.logging },
@@ -821,18 +943,27 @@ function initConfig() {
821
943
  function getConfigForEnv() {
822
944
  const config = loadConfig();
823
945
  const env = {};
824
- if (config.embedding.provider === "ollama") {
946
+ const provider = config.embedding.provider;
947
+ if (provider === "ollama") {
825
948
  env.OLLAMA_EMBEDDING_MODEL = config.embedding.model;
826
949
  env.OLLAMA_BASE_URL = config.embedding.baseURL || "http://localhost:11434";
827
950
  if (config.embedding.dimensions) {
828
951
  env.OLLAMA_EMBEDDING_DIMENSIONS = String(config.embedding.dimensions);
829
952
  }
830
- } else if (config.embedding.provider === "mistral") {
953
+ } else if (provider === "lmstudio") {
954
+ env.LMSTUDIO_EMBEDDING_MODEL = config.embedding.model;
955
+ env.LMSTUDIO_BASE_URL = config.embedding.baseURL || INFERENCE_PROVIDERS.lmstudio.defaultEmbeddingBaseUrl;
956
+ if (config.embedding.dimensions) {
957
+ env.LMSTUDIO_EMBEDDING_DIMENSIONS = String(config.embedding.dimensions);
958
+ }
959
+ } else if (provider === "mistral") {
831
960
  env.MISTRAL_API_KEY = config.embedding.apiKey || "";
832
961
  env.MISTRAL_TEXT_EMBEDDING_MODEL = config.embedding.model;
833
- } else if (config.embedding.provider === "openai") {
962
+ } else if (provider === "openai") {
834
963
  env.OPENAI_API_KEY = config.embedding.apiKey || "";
835
964
  env.OPENAI_EMBEDDING_MODEL = config.embedding.model;
965
+ } else {
966
+ console.error(`[getConfigForEnv] embedding.provider "${provider}" has no env-projection branch \u2014 no embedding env vars were set`);
836
967
  }
837
968
  env.LOG_LEVEL = config.logging.level;
838
969
  env.ENABLE_METRICS = String(config.logging.enableMetrics);
@@ -842,6 +973,7 @@ var CONFIG_DIR, CONFIG_FILE, ConfigParseError, ConfigWriteConflictError, migrati
842
973
  var init_config_loader = __esm(() => {
843
974
  init_massa_ai_config();
844
975
  init_xdg();
976
+ init_inference_providers();
845
977
  CONFIG_DIR = configDir("massa-ai");
846
978
  CONFIG_FILE = path3.join(CONFIG_DIR, "config.json");
847
979
  ConfigParseError = class ConfigParseError extends Error {
@@ -901,6 +1033,7 @@ try {
901
1033
  // ../../packages/shared/dist/config/index.js
902
1034
  init_config_loader();
903
1035
  init_massa_ai_config();
1036
+ init_inference_providers();
904
1037
  init_massa_ai_config();
905
1038
  init_massa_ai_config();
906
1039
  init_config_loader();
@@ -917,8 +1050,7 @@ init_xdg();
917
1050
  init_config_loader();
918
1051
 
919
1052
  // ../../packages/shared/dist/config/index.js
920
- var DEFAULT_LLM_MODEL = "qwen2.5:7b-instruct";
921
- var DEFAULT_LLM_CODE_MODEL = "qwen2.5-coder:7b";
1053
+ init_embedding_dimensions();
922
1054
  function envNum(key, fallback) {
923
1055
  const s = process.env[key];
924
1056
  if (s === undefined || s === "")
@@ -1091,6 +1223,15 @@ var DEFAULT_ALLOWED_EXTENSIONS = [
1091
1223
  ".hs"
1092
1224
  ];
1093
1225
  var fileConfig = loadConfigSafe();
1226
+ function activeInferenceProviderId() {
1227
+ const providerId = fileConfig.embedding?.provider;
1228
+ if (providerId && LOCAL_INFERENCE_IDS.includes(providerId)) {
1229
+ return providerId;
1230
+ }
1231
+ return "ollama";
1232
+ }
1233
+ var DEFAULT_LLM_MODEL = INFERENCE_PROVIDERS[activeInferenceProviderId()].defaultModels.instruct;
1234
+ var DEFAULT_LLM_CODE_MODEL = INFERENCE_PROVIDERS[activeInferenceProviderId()].defaultModels.coding;
1094
1235
  var fileCacheL1Bytes = fileConfig.cache?.l1MaxSizeMB ? fileConfig.cache.l1MaxSizeMB * 1024 * 1024 : undefined;
1095
1236
  var fileCacheL2Bytes = fileConfig.cache?.l2MaxSizeMB ? fileConfig.cache.l2MaxSizeMB * 1024 * 1024 : undefined;
1096
1237
  var resolvedDataDir = getGlobalDataDir();
@@ -1133,7 +1274,10 @@ var defaultConfig = {
1133
1274
  temperature: envNum("MASSA_AI_LLM_TEMPERATURE", fileConfig.llm?.temperature ?? 0.2),
1134
1275
  maxOutputTokens: envNum("MASSA_AI_LLM_MAX_OUTPUT_TOKENS", fileConfig.llm?.maxOutputTokens ?? 8000),
1135
1276
  timeoutMs: envNum("MASSA_AI_LLM_TIMEOUT_MS", fileConfig.llm?.timeoutMs ?? 90000),
1136
- disableThink: envBool("MASSA_AI_LLM_DISABLE_THINK", fileConfig.llm?.disableThink ?? true)
1277
+ disableThink: envBool("MASSA_AI_LLM_DISABLE_THINK", fileConfig.llm?.disableThink ?? true),
1278
+ contextWindow: fileConfig.llm?.contextWindow ?? INFERENCE_ROLE_DEFAULTS.instruct.contextWindow,
1279
+ codeContextWindow: fileConfig.llm?.codeContextWindow ?? INFERENCE_ROLE_DEFAULTS.coding.contextWindow,
1280
+ codeTemperature: envNum("MASSA_AI_LLM_CODE_TEMPERATURE", fileConfig.llm?.codeTemperature ?? INFERENCE_ROLE_DEFAULTS.coding.temperature)
1137
1281
  },
1138
1282
  memory: {
1139
1283
  decay: {
@@ -3275,11 +3419,13 @@ function formatBootstrapReport(report) {
3275
3419
  // ../../packages/shared/dist/bootstrap/index.js
3276
3420
  init_config_loader();
3277
3421
  // src/config-cli.ts
3422
+ init_inference_providers();
3278
3423
  import { promises as fs11 } from "fs";
3279
3424
  import path15 from "path";
3280
3425
  import os8 from "os";
3281
3426
  import { fileURLToPath } from "url";
3282
3427
  var __dirname2 = path15.dirname(fileURLToPath(import.meta.url));
3428
+ var WRITABLE_PROVIDERS = ["ollama", "lmstudio", "mistral", "openai", "google", "cohere"];
3283
3429
  var GENERATOR_MARKER = "scripts/generate-subagent-artifacts.ts";
3284
3430
  var GENERATOR_MARKER_MAX_LEVELS = 6;
3285
3431
  function formatVariantSync(results) {
@@ -3299,16 +3445,18 @@ Usage:
3299
3445
  Commands:
3300
3446
  init Initialize massa-ai configuration
3301
3447
  --ollama Use Ollama (local, default)
3448
+ --lmstudio Use LM Studio (local)
3302
3449
  --mistral <key> Use Mistral with API key
3303
3450
  --openai <key> Use OpenAI with API key
3304
3451
 
3305
3452
  path Show config file path
3306
3453
  show Show current configuration
3307
3454
  set <key> <val> Set a configuration value
3308
- use <provider> Switch embedding provider
3309
- --api-key <key> API key (required for mistral/openai)
3455
+ use <provider> Switch embedding provider (ollama, lmstudio, mistral,
3456
+ openai, google, cohere)
3457
+ --api-key <key> API key (required for mistral/openai/google/cohere)
3310
3458
  --model <name> Model name
3311
- --base-url <url> Base URL (for ollama)
3459
+ --base-url <url> Base URL (for ollama/lmstudio)
3312
3460
 
3313
3461
  agents Manage the 18 subagent specialist definitions
3314
3462
  agents install [--user|--project] Write 18 agent .md files
@@ -3328,8 +3476,10 @@ Commands:
3328
3476
 
3329
3477
  Examples:
3330
3478
  massa-ai-config init
3479
+ massa-ai-config init --lmstudio
3331
3480
  massa-ai-config init --mistral your-api-key
3332
- massa-ai-config use ollama --model qwen3-embedding:4b
3481
+ massa-ai-config use ollama --model qwen3-embedding:0.6b
3482
+ massa-ai-config use lmstudio
3333
3483
  massa-ai-config use mistral --api-key your-key
3334
3484
  massa-ai-config set embedding.dimensions 1024
3335
3485
  massa-ai-config agents install --user
@@ -3408,6 +3558,20 @@ async function runCli(argv) {
3408
3558
  };
3409
3559
  saveConfig(config2);
3410
3560
  console.log("\u2713 Configured for OpenAI embeddings");
3561
+ } else if (options.lmstudio) {
3562
+ const config2 = loadConfig();
3563
+ const model = INFERENCE_PROVIDERS.lmstudio.defaultModels.embedding;
3564
+ config2.embedding = {
3565
+ provider: "lmstudio",
3566
+ model,
3567
+ baseURL: INFERENCE_PROVIDERS.lmstudio.defaultEmbeddingBaseUrl,
3568
+ dimensions: INFERENCE_PROVIDERS.lmstudio.knownDimensions[model] ?? 768
3569
+ };
3570
+ config2.llm.baseUrl = INFERENCE_PROVIDERS.lmstudio.defaultLlmBaseUrl;
3571
+ config2.llm.model = INFERENCE_PROVIDERS.lmstudio.defaultModels.instruct;
3572
+ config2.llm.codeModel = INFERENCE_PROVIDERS.lmstudio.defaultModels.coding;
3573
+ saveConfig(config2);
3574
+ console.log("\u2713 Configured for LM Studio (local) embeddings");
3411
3575
  } else {
3412
3576
  console.log("\u2713 Configured for Ollama (local) embeddings");
3413
3577
  }
@@ -3452,18 +3616,35 @@ Using defaults:`);
3452
3616
  }
3453
3617
  case "use": {
3454
3618
  const provider = args[1];
3455
- if (!provider || !["ollama", "mistral", "openai"].includes(provider)) {
3456
- console.error("Provider must be: ollama, mistral, or openai");
3619
+ if (!provider || !WRITABLE_PROVIDERS.includes(provider)) {
3620
+ console.error(`Provider must be one of: ${WRITABLE_PROVIDERS.join(", ")}`);
3457
3621
  return 1;
3458
3622
  }
3459
3623
  const config2 = loadConfig();
3460
3624
  if (provider === "ollama") {
3625
+ const model = options.model || INFERENCE_PROVIDERS.ollama.defaultModels.embedding;
3626
+ const urls = deriveInferenceBaseUrls("ollama", options["base-url"]);
3461
3627
  config2.embedding = {
3462
3628
  provider: "ollama",
3463
- model: options.model || "qwen3-embedding:4b",
3464
- baseURL: options["base-url"] || "http://localhost:11434",
3465
- dimensions: 2560
3629
+ model,
3630
+ baseURL: urls.embeddingBaseUrl,
3631
+ dimensions: knownEmbeddingDimensions(model) ?? 768
3632
+ };
3633
+ config2.llm.baseUrl = urls.llmBaseUrl;
3634
+ config2.llm.model = INFERENCE_PROVIDERS.ollama.defaultModels.instruct;
3635
+ config2.llm.codeModel = INFERENCE_PROVIDERS.ollama.defaultModels.coding;
3636
+ } else if (provider === "lmstudio") {
3637
+ const model = options.model || INFERENCE_PROVIDERS.lmstudio.defaultModels.embedding;
3638
+ const urls = deriveInferenceBaseUrls("lmstudio", options["base-url"]);
3639
+ config2.embedding = {
3640
+ provider: "lmstudio",
3641
+ model,
3642
+ baseURL: urls.embeddingBaseUrl,
3643
+ dimensions: INFERENCE_PROVIDERS.lmstudio.knownDimensions[model] ?? 768
3466
3644
  };
3645
+ config2.llm.baseUrl = urls.llmBaseUrl;
3646
+ config2.llm.model = INFERENCE_PROVIDERS.lmstudio.defaultModels.instruct;
3647
+ config2.llm.codeModel = INFERENCE_PROVIDERS.lmstudio.defaultModels.coding;
3467
3648
  } else if (provider === "mistral") {
3468
3649
  if (!options["api-key"]) {
3469
3650
  console.error("Error: --api-key required for Mistral");
@@ -3486,6 +3667,28 @@ Using defaults:`);
3486
3667
  apiKey: options["api-key"],
3487
3668
  dimensions: 1536
3488
3669
  };
3670
+ } else if (provider === "google") {
3671
+ if (!options["api-key"]) {
3672
+ console.error("Error: --api-key required for Google");
3673
+ return 1;
3674
+ }
3675
+ config2.embedding = {
3676
+ provider: "google",
3677
+ model: options.model || "gemini-embedding-001",
3678
+ apiKey: options["api-key"],
3679
+ dimensions: 3072
3680
+ };
3681
+ } else if (provider === "cohere") {
3682
+ if (!options["api-key"]) {
3683
+ console.error("Error: --api-key required for Cohere");
3684
+ return 1;
3685
+ }
3686
+ config2.embedding = {
3687
+ provider: "cohere",
3688
+ model: options.model || "embed-english-v3.0",
3689
+ apiKey: options["api-key"],
3690
+ dimensions: 1024
3691
+ };
3489
3692
  }
3490
3693
  saveConfig(config2);
3491
3694
  console.log(`\u2713 Switched to ${provider} embeddings`);
package/dist/index.js CHANGED
@@ -398,11 +398,129 @@ function configDir(app) {
398
398
  }
399
399
  var init_xdg = () => {};
400
400
 
401
+ // ../../packages/shared/dist/config/embedding-dimensions.js
402
+ function knownEmbeddingDimensions(model) {
403
+ if (!model)
404
+ return;
405
+ return KNOWN_EMBEDDING_DIMENSIONS[model.trim()];
406
+ }
407
+ var KNOWN_EMBEDDING_DIMENSIONS;
408
+ var init_embedding_dimensions = __esm(() => {
409
+ KNOWN_EMBEDDING_DIMENSIONS = {
410
+ "qwen3-embedding:8b": 4096,
411
+ "qwen3-embedding:4b": 2560,
412
+ "qwen3-embedding:0.6b": 1024,
413
+ "bge-m3": 1024
414
+ };
415
+ });
416
+
417
+ // ../../packages/shared/dist/config/inference-providers.js
418
+ function parseOllamaModelList(body) {
419
+ if (typeof body !== "object" || body === null)
420
+ return null;
421
+ const models = body.models;
422
+ if (!Array.isArray(models))
423
+ return null;
424
+ return models.map((entry) => entry.name).filter((name) => typeof name === "string");
425
+ }
426
+ function parseLmStudioModelList(body) {
427
+ if (typeof body !== "object" || body === null)
428
+ return null;
429
+ const data = body.data;
430
+ if (!Array.isArray(data))
431
+ return null;
432
+ return data.map((entry) => entry.id).filter((id) => typeof id === "string");
433
+ }
434
+ function deriveInferenceBaseUrls(providerId, explicitBaseUrl) {
435
+ const spec = INFERENCE_PROVIDERS[providerId];
436
+ if (!explicitBaseUrl) {
437
+ return {
438
+ embeddingBaseUrl: spec.defaultEmbeddingBaseUrl,
439
+ llmBaseUrl: spec.defaultLlmBaseUrl
440
+ };
441
+ }
442
+ let end = explicitBaseUrl.length;
443
+ while (end > 0 && explicitBaseUrl.charCodeAt(end - 1) === SLASH)
444
+ end--;
445
+ const base = explicitBaseUrl.slice(0, end);
446
+ const suffix = spec.defaultLlmBaseUrl.startsWith(spec.defaultEmbeddingBaseUrl) ? spec.defaultLlmBaseUrl.slice(spec.defaultEmbeddingBaseUrl.length) : "";
447
+ return {
448
+ embeddingBaseUrl: base,
449
+ llmBaseUrl: `${base}${suffix}`
450
+ };
451
+ }
452
+ var LOCAL_INFERENCE_IDS, INFERENCE_ROLE_DEFAULTS, INFERENCE_PROVIDERS, SLASH = 47;
453
+ var init_inference_providers = __esm(() => {
454
+ init_embedding_dimensions();
455
+ LOCAL_INFERENCE_IDS = ["ollama", "lmstudio"];
456
+ INFERENCE_ROLE_DEFAULTS = {
457
+ embedding: { contextWindow: 8192 },
458
+ instruct: { contextWindow: 16384, temperature: 0.2 },
459
+ coding: { contextWindow: 32768, temperature: 0 }
460
+ };
461
+ INFERENCE_PROVIDERS = {
462
+ ollama: {
463
+ id: "ollama",
464
+ defaultEmbeddingBaseUrl: "http://localhost:11434",
465
+ defaultLlmBaseUrl: "http://localhost:11434/v1",
466
+ envNames: {
467
+ model: "OLLAMA_EMBEDDING_MODEL",
468
+ baseUrl: "OLLAMA_BASE_URL",
469
+ dimensions: "OLLAMA_EMBEDDING_DIMENSIONS"
470
+ },
471
+ knownDimensions: KNOWN_EMBEDDING_DIMENSIONS,
472
+ defaultModels: {
473
+ embedding: "qwen3-embedding:0.6b",
474
+ instruct: "qwen3-vl:8b",
475
+ coding: "qwen2.5-coder:7b"
476
+ },
477
+ appliesContextPerRequest: true,
478
+ embedBatchSize: 64,
479
+ supportsOllamaVersionProbe: true,
480
+ injectsDisableThink: true,
481
+ requiresChatCompletionsApi: false,
482
+ parseModelList: parseOllamaModelList
483
+ },
484
+ lmstudio: {
485
+ id: "lmstudio",
486
+ defaultEmbeddingBaseUrl: "http://localhost:1234/v1",
487
+ defaultLlmBaseUrl: "http://localhost:1234/v1",
488
+ envNames: {
489
+ model: "LMSTUDIO_EMBEDDING_MODEL",
490
+ baseUrl: "LMSTUDIO_BASE_URL",
491
+ dimensions: "LMSTUDIO_EMBEDDING_DIMENSIONS"
492
+ },
493
+ knownDimensions: {
494
+ "text-embedding-nomic-embed-text-v1.5": 768,
495
+ "text-embedding-qwen3-embedding-0.6b": 1024
496
+ },
497
+ defaultModels: {
498
+ embedding: "text-embedding-qwen3-embedding-0.6b",
499
+ instruct: "qwen3-vl-8b-instruct",
500
+ coding: "qwen2.5-coder-7b-instruct"
501
+ },
502
+ appliesContextPerRequest: false,
503
+ embedBatchSize: 64,
504
+ supportsOllamaVersionProbe: false,
505
+ injectsDisableThink: false,
506
+ requiresChatCompletionsApi: true,
507
+ parseModelList: parseLmStudioModelList
508
+ }
509
+ };
510
+ });
511
+
401
512
  // ../../packages/shared/dist/config/massa-ai-config.js
402
513
  import path2 from "path";
403
- var SCHEDULER_JOB_KINDS, MAX_MATCH_WORK = 1e5, MAX_IGNORE_PATTERNS = 1024, DEFAULT_CAPTURE_POLICY, DEFAULT_SCHEDULER_CONFIG, defaultMassaAiConfig;
514
+ var API_PROVIDER_IDS, EMBEDDING_PROVIDER_IDS, SCHEDULER_JOB_KINDS, MAX_MATCH_WORK = 1e5, MAX_IGNORE_PATTERNS = 1024, DEFAULT_CAPTURE_POLICY, DEFAULT_SCHEDULER_CONFIG, defaultMassaAiConfig;
404
515
  var init_massa_ai_config = __esm(() => {
405
516
  init_xdg();
517
+ init_inference_providers();
518
+ init_embedding_dimensions();
519
+ API_PROVIDER_IDS = ["mistral", "openai", "google", "cohere"];
520
+ EMBEDDING_PROVIDER_IDS = [
521
+ ...LOCAL_INFERENCE_IDS,
522
+ ...API_PROVIDER_IDS
523
+ ];
406
524
  SCHEDULER_JOB_KINDS = [
407
525
  "memory-consolidation",
408
526
  "decay-sweep",
@@ -464,9 +582,9 @@ var init_massa_ai_config = __esm(() => {
464
582
  },
465
583
  embedding: {
466
584
  provider: "ollama",
467
- model: "qwen3-embedding:4b",
585
+ model: INFERENCE_PROVIDERS.ollama.defaultModels.embedding,
468
586
  baseURL: "http://localhost:11434",
469
- dimensions: 2560
587
+ dimensions: knownEmbeddingDimensions(INFERENCE_PROVIDERS.ollama.defaultModels.embedding) ?? 768
470
588
  },
471
589
  compression: {
472
590
  defaultStrategy: "code_structure",
@@ -505,12 +623,15 @@ var init_massa_ai_config = __esm(() => {
505
623
  enabled: false,
506
624
  baseUrl: "http://localhost:11434/v1",
507
625
  apiKey: "ollama",
508
- model: "qwen2.5:7b-instruct",
509
- codeModel: "qwen2.5-coder:7b",
626
+ model: INFERENCE_PROVIDERS.ollama.defaultModels.instruct,
627
+ codeModel: INFERENCE_PROVIDERS.ollama.defaultModels.coding,
510
628
  temperature: 0.2,
511
629
  maxOutputTokens: 8000,
512
630
  timeoutMs: 90000,
513
- disableThink: true
631
+ disableThink: true,
632
+ contextWindow: INFERENCE_ROLE_DEFAULTS.instruct.contextWindow,
633
+ codeContextWindow: INFERENCE_ROLE_DEFAULTS.coding.contextWindow,
634
+ codeTemperature: INFERENCE_ROLE_DEFAULTS.coding.temperature
514
635
  },
515
636
  memory: {
516
637
  decay: {
@@ -671,11 +792,12 @@ function loadConfig() {
671
792
  try {
672
793
  const content = fs.readFileSync(CONFIG_FILE, "utf-8");
673
794
  const userConfig = JSON.parse(content);
795
+ const embeddingBase = userConfig.embedding?.provider && userConfig.embedding.provider !== defaultMassaAiConfig.embedding.provider ? {} : defaultMassaAiConfig.embedding;
674
796
  return {
675
797
  ...defaultMassaAiConfig,
676
798
  ...userConfig,
677
799
  database: { ...defaultMassaAiConfig.database, ...userConfig.database },
678
- embedding: { ...defaultMassaAiConfig.embedding, ...userConfig.embedding },
800
+ embedding: { ...embeddingBase, ...userConfig.embedding },
679
801
  compression: { ...defaultMassaAiConfig.compression, ...userConfig.compression },
680
802
  cache: { ...defaultMassaAiConfig.cache, ...userConfig.cache },
681
803
  logging: { ...defaultMassaAiConfig.logging, ...userConfig.logging },
@@ -820,18 +942,27 @@ function initConfig() {
820
942
  function getConfigForEnv() {
821
943
  const config = loadConfig();
822
944
  const env = {};
823
- if (config.embedding.provider === "ollama") {
945
+ const provider = config.embedding.provider;
946
+ if (provider === "ollama") {
824
947
  env.OLLAMA_EMBEDDING_MODEL = config.embedding.model;
825
948
  env.OLLAMA_BASE_URL = config.embedding.baseURL || "http://localhost:11434";
826
949
  if (config.embedding.dimensions) {
827
950
  env.OLLAMA_EMBEDDING_DIMENSIONS = String(config.embedding.dimensions);
828
951
  }
829
- } else if (config.embedding.provider === "mistral") {
952
+ } else if (provider === "lmstudio") {
953
+ env.LMSTUDIO_EMBEDDING_MODEL = config.embedding.model;
954
+ env.LMSTUDIO_BASE_URL = config.embedding.baseURL || INFERENCE_PROVIDERS.lmstudio.defaultEmbeddingBaseUrl;
955
+ if (config.embedding.dimensions) {
956
+ env.LMSTUDIO_EMBEDDING_DIMENSIONS = String(config.embedding.dimensions);
957
+ }
958
+ } else if (provider === "mistral") {
830
959
  env.MISTRAL_API_KEY = config.embedding.apiKey || "";
831
960
  env.MISTRAL_TEXT_EMBEDDING_MODEL = config.embedding.model;
832
- } else if (config.embedding.provider === "openai") {
961
+ } else if (provider === "openai") {
833
962
  env.OPENAI_API_KEY = config.embedding.apiKey || "";
834
963
  env.OPENAI_EMBEDDING_MODEL = config.embedding.model;
964
+ } else {
965
+ console.error(`[getConfigForEnv] embedding.provider "${provider}" has no env-projection branch \u2014 no embedding env vars were set`);
835
966
  }
836
967
  env.LOG_LEVEL = config.logging.level;
837
968
  env.ENABLE_METRICS = String(config.logging.enableMetrics);
@@ -841,6 +972,7 @@ var CONFIG_DIR, CONFIG_FILE, ConfigParseError, ConfigWriteConflictError, migrati
841
972
  var init_config_loader = __esm(() => {
842
973
  init_massa_ai_config();
843
974
  init_xdg();
975
+ init_inference_providers();
844
976
  CONFIG_DIR = configDir("massa-ai");
845
977
  CONFIG_FILE = path3.join(CONFIG_DIR, "config.json");
846
978
  ConfigParseError = class ConfigParseError extends Error {
@@ -900,6 +1032,7 @@ try {
900
1032
  // ../../packages/shared/dist/config/index.js
901
1033
  init_config_loader();
902
1034
  init_massa_ai_config();
1035
+ init_inference_providers();
903
1036
  init_massa_ai_config();
904
1037
  init_massa_ai_config();
905
1038
  init_config_loader();
@@ -916,8 +1049,7 @@ init_xdg();
916
1049
  init_config_loader();
917
1050
 
918
1051
  // ../../packages/shared/dist/config/index.js
919
- var DEFAULT_LLM_MODEL = "qwen2.5:7b-instruct";
920
- var DEFAULT_LLM_CODE_MODEL = "qwen2.5-coder:7b";
1052
+ init_embedding_dimensions();
921
1053
  function envNum(key, fallback) {
922
1054
  const s = process.env[key];
923
1055
  if (s === undefined || s === "")
@@ -1090,6 +1222,15 @@ var DEFAULT_ALLOWED_EXTENSIONS = [
1090
1222
  ".hs"
1091
1223
  ];
1092
1224
  var fileConfig = loadConfigSafe();
1225
+ function activeInferenceProviderId() {
1226
+ const providerId = fileConfig.embedding?.provider;
1227
+ if (providerId && LOCAL_INFERENCE_IDS.includes(providerId)) {
1228
+ return providerId;
1229
+ }
1230
+ return "ollama";
1231
+ }
1232
+ var DEFAULT_LLM_MODEL = INFERENCE_PROVIDERS[activeInferenceProviderId()].defaultModels.instruct;
1233
+ var DEFAULT_LLM_CODE_MODEL = INFERENCE_PROVIDERS[activeInferenceProviderId()].defaultModels.coding;
1093
1234
  var fileCacheL1Bytes = fileConfig.cache?.l1MaxSizeMB ? fileConfig.cache.l1MaxSizeMB * 1024 * 1024 : undefined;
1094
1235
  var fileCacheL2Bytes = fileConfig.cache?.l2MaxSizeMB ? fileConfig.cache.l2MaxSizeMB * 1024 * 1024 : undefined;
1095
1236
  var resolvedDataDir = getGlobalDataDir();
@@ -1132,7 +1273,10 @@ var defaultConfig = {
1132
1273
  temperature: envNum("MASSA_AI_LLM_TEMPERATURE", fileConfig.llm?.temperature ?? 0.2),
1133
1274
  maxOutputTokens: envNum("MASSA_AI_LLM_MAX_OUTPUT_TOKENS", fileConfig.llm?.maxOutputTokens ?? 8000),
1134
1275
  timeoutMs: envNum("MASSA_AI_LLM_TIMEOUT_MS", fileConfig.llm?.timeoutMs ?? 90000),
1135
- disableThink: envBool("MASSA_AI_LLM_DISABLE_THINK", fileConfig.llm?.disableThink ?? true)
1276
+ disableThink: envBool("MASSA_AI_LLM_DISABLE_THINK", fileConfig.llm?.disableThink ?? true),
1277
+ contextWindow: fileConfig.llm?.contextWindow ?? INFERENCE_ROLE_DEFAULTS.instruct.contextWindow,
1278
+ codeContextWindow: fileConfig.llm?.codeContextWindow ?? INFERENCE_ROLE_DEFAULTS.coding.contextWindow,
1279
+ codeTemperature: envNum("MASSA_AI_LLM_CODE_TEMPERATURE", fileConfig.llm?.codeTemperature ?? INFERENCE_ROLE_DEFAULTS.coding.temperature)
1136
1280
  },
1137
1281
  memory: {
1138
1282
  decay: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@massa-ai/opencode-plugin",
3
- "version": "1.57.0",
3
+ "version": "1.59.0",
4
4
  "description": "massa-ai plugin for OpenCode - Semantic code search, memory, and context compression",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -24,8 +24,8 @@
24
24
  "dependencies": {
25
25
  "@opencode-ai/plugin": "^1.2.15",
26
26
  "@opencode-ai/sdk": "^1.2.15",
27
- "@massa-ai/core": "^1.57.0",
28
- "@massa-ai/shared": "^1.57.0"
27
+ "@massa-ai/core": "^1.59.0",
28
+ "@massa-ai/shared": "^1.59.0"
29
29
  },
30
30
  "devDependencies": {
31
31
  "@types/node": "^22.10.5",