@massa-ai/mcp-client 1.58.0 → 1.60.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.
@@ -444,10 +444,33 @@ function parseLmStudioModelList(body) {
444
444
  function inferenceProviderList() {
445
445
  return LOCAL_INFERENCE_IDS.map((id) => INFERENCE_PROVIDERS[id]);
446
446
  }
447
- var LOCAL_INFERENCE_IDS, INFERENCE_PROVIDERS;
447
+ function deriveInferenceBaseUrls(providerId, explicitBaseUrl) {
448
+ const spec = INFERENCE_PROVIDERS[providerId];
449
+ if (!explicitBaseUrl) {
450
+ return {
451
+ embeddingBaseUrl: spec.defaultEmbeddingBaseUrl,
452
+ llmBaseUrl: spec.defaultLlmBaseUrl
453
+ };
454
+ }
455
+ let end = explicitBaseUrl.length;
456
+ while (end > 0 && explicitBaseUrl.charCodeAt(end - 1) === SLASH)
457
+ end--;
458
+ const base = explicitBaseUrl.slice(0, end);
459
+ const suffix = spec.defaultLlmBaseUrl.startsWith(spec.defaultEmbeddingBaseUrl) ? spec.defaultLlmBaseUrl.slice(spec.defaultEmbeddingBaseUrl.length) : "";
460
+ return {
461
+ embeddingBaseUrl: base,
462
+ llmBaseUrl: `${base}${suffix}`
463
+ };
464
+ }
465
+ var LOCAL_INFERENCE_IDS, INFERENCE_ROLE_DEFAULTS, INFERENCE_PROVIDERS, SLASH = 47;
448
466
  var init_inference_providers = __esm(() => {
449
467
  init_embedding_dimensions();
450
468
  LOCAL_INFERENCE_IDS = ["ollama", "lmstudio"];
469
+ INFERENCE_ROLE_DEFAULTS = {
470
+ embedding: { contextWindow: 8192 },
471
+ instruct: { contextWindow: 16384, temperature: 0.2 },
472
+ coding: { contextWindow: 32768, temperature: 0 }
473
+ };
451
474
  INFERENCE_PROVIDERS = {
452
475
  ollama: {
453
476
  id: "ollama",
@@ -459,6 +482,13 @@ var init_inference_providers = __esm(() => {
459
482
  dimensions: "OLLAMA_EMBEDDING_DIMENSIONS"
460
483
  },
461
484
  knownDimensions: KNOWN_EMBEDDING_DIMENSIONS,
485
+ defaultModels: {
486
+ embedding: "qwen3-embedding:0.6b",
487
+ instruct: "qwen3-vl:8b",
488
+ coding: "qwen2.5-coder:7b"
489
+ },
490
+ appliesContextPerRequest: true,
491
+ embedBatchSize: 64,
462
492
  supportsOllamaVersionProbe: true,
463
493
  injectsDisableThink: true,
464
494
  requiresChatCompletionsApi: false,
@@ -474,8 +504,36 @@ var init_inference_providers = __esm(() => {
474
504
  dimensions: "LMSTUDIO_EMBEDDING_DIMENSIONS"
475
505
  },
476
506
  knownDimensions: {
477
- "text-embedding-nomic-embed-text-v1.5": 768
507
+ "text-embedding-nomic-embed-text-v1.5": 768,
508
+ "text-embedding-qwen3-embedding-0.6b": 1024,
509
+ "qwen3-embedding-0.6b-dwq": 1024
510
+ },
511
+ defaultModels: {
512
+ embedding: "text-embedding-qwen3-embedding-0.6b",
513
+ instruct: "qwen3-vl-8b-instruct",
514
+ coding: "qwen2.5-coder-7b-instruct"
515
+ },
516
+ mlxModels: {
517
+ embedding: {
518
+ repo: "mlx-community/Qwen3-Embedding-0.6B-4bit-DWQ",
519
+ model: "qwen3-embedding-0.6b-dwq"
520
+ },
521
+ instruct: {
522
+ repo: "mlx-community/Qwen3-VL-8B-Instruct-4bit",
523
+ model: "qwen3-vl-8b-instruct"
524
+ },
525
+ coding: {
526
+ repo: "mlx-community/Qwen2.5-Coder-7B-Instruct-4bit",
527
+ model: "qwen2.5-coder-7b-instruct"
528
+ }
529
+ },
530
+ ggufRepos: {
531
+ embedding: "Qwen/Qwen3-Embedding-0.6B-GGUF",
532
+ instruct: "lmstudio-community/Qwen3-VL-8B-Instruct-GGUF",
533
+ coding: "lmstudio-community/Qwen2.5-Coder-7B-Instruct-GGUF"
478
534
  },
535
+ appliesContextPerRequest: false,
536
+ embedBatchSize: 64,
479
537
  supportsOllamaVersionProbe: false,
480
538
  injectsDisableThink: false,
481
539
  requiresChatCompletionsApi: true,
@@ -490,6 +548,7 @@ var API_PROVIDER_IDS, EMBEDDING_PROVIDER_IDS, SCHEDULER_JOB_KINDS, MAX_MATCH_WOR
490
548
  var init_massa_ai_config = __esm(() => {
491
549
  init_xdg();
492
550
  init_inference_providers();
551
+ init_embedding_dimensions();
493
552
  API_PROVIDER_IDS = ["mistral", "openai", "google", "cohere"];
494
553
  EMBEDDING_PROVIDER_IDS = [
495
554
  ...LOCAL_INFERENCE_IDS,
@@ -556,9 +615,9 @@ var init_massa_ai_config = __esm(() => {
556
615
  },
557
616
  embedding: {
558
617
  provider: "ollama",
559
- model: "qwen3-embedding:4b",
618
+ model: INFERENCE_PROVIDERS.ollama.defaultModels.embedding,
560
619
  baseURL: "http://localhost:11434",
561
- dimensions: 2560
620
+ dimensions: knownEmbeddingDimensions(INFERENCE_PROVIDERS.ollama.defaultModels.embedding) ?? 768
562
621
  },
563
622
  compression: {
564
623
  defaultStrategy: "code_structure",
@@ -597,12 +656,15 @@ var init_massa_ai_config = __esm(() => {
597
656
  enabled: false,
598
657
  baseUrl: "http://localhost:11434/v1",
599
658
  apiKey: "ollama",
600
- model: "qwen2.5:7b-instruct",
601
- codeModel: "qwen2.5-coder:7b",
659
+ model: INFERENCE_PROVIDERS.ollama.defaultModels.instruct,
660
+ codeModel: INFERENCE_PROVIDERS.ollama.defaultModels.coding,
602
661
  temperature: 0.2,
603
662
  maxOutputTokens: 8000,
604
663
  timeoutMs: 90000,
605
- disableThink: true
664
+ disableThink: true,
665
+ contextWindow: INFERENCE_ROLE_DEFAULTS.instruct.contextWindow,
666
+ codeContextWindow: INFERENCE_ROLE_DEFAULTS.coding.contextWindow,
667
+ codeTemperature: INFERENCE_ROLE_DEFAULTS.coding.temperature
606
668
  },
607
669
  memory: {
608
670
  decay: {
@@ -1157,6 +1219,13 @@ function getGlobalDataDir() {
1157
1219
  return fileConfig.dataDir;
1158
1220
  return path4.join(getConfigDir(), "data");
1159
1221
  }
1222
+ function activeInferenceProviderId() {
1223
+ const providerId = fileConfig.embedding?.provider;
1224
+ if (providerId && LOCAL_INFERENCE_IDS.includes(providerId)) {
1225
+ return providerId;
1226
+ }
1227
+ return "ollama";
1228
+ }
1160
1229
 
1161
1230
  class Config {
1162
1231
  config;
@@ -1293,11 +1362,12 @@ class Config {
1293
1362
  this.config[key] = value;
1294
1363
  }
1295
1364
  }
1296
- var DEFAULT_LLM_MODEL = "qwen2.5:7b-instruct", DEFAULT_LLM_CODE_MODEL = "qwen2.5-coder:7b", SCHEDULER_JOB_ENV, DEFAULT_ALLOWED_EXTENSIONS, fileConfig, fileCacheL1Bytes, fileCacheL2Bytes, resolvedDataDir, defaultConfig, config;
1365
+ var SCHEDULER_JOB_ENV, DEFAULT_ALLOWED_EXTENSIONS, fileConfig, DEFAULT_LLM_MODEL, DEFAULT_LLM_CODE_MODEL, fileCacheL1Bytes, fileCacheL2Bytes, resolvedDataDir, defaultConfig, config;
1297
1366
  var init_config = __esm(() => {
1298
1367
  init_env();
1299
1368
  init_config_loader();
1300
1369
  init_massa_ai_config();
1370
+ init_inference_providers();
1301
1371
  init_massa_ai_config();
1302
1372
  init_massa_ai_config();
1303
1373
  init_config_loader();
@@ -1368,6 +1438,8 @@ var init_config = __esm(() => {
1368
1438
  ".hs"
1369
1439
  ];
1370
1440
  fileConfig = loadConfigSafe();
1441
+ DEFAULT_LLM_MODEL = INFERENCE_PROVIDERS[activeInferenceProviderId()].defaultModels.instruct;
1442
+ DEFAULT_LLM_CODE_MODEL = INFERENCE_PROVIDERS[activeInferenceProviderId()].defaultModels.coding;
1371
1443
  fileCacheL1Bytes = fileConfig.cache?.l1MaxSizeMB ? fileConfig.cache.l1MaxSizeMB * 1024 * 1024 : undefined;
1372
1444
  fileCacheL2Bytes = fileConfig.cache?.l2MaxSizeMB ? fileConfig.cache.l2MaxSizeMB * 1024 * 1024 : undefined;
1373
1445
  resolvedDataDir = getGlobalDataDir();
@@ -1410,7 +1482,10 @@ var init_config = __esm(() => {
1410
1482
  temperature: envNum("MASSA_AI_LLM_TEMPERATURE", fileConfig.llm?.temperature ?? 0.2),
1411
1483
  maxOutputTokens: envNum("MASSA_AI_LLM_MAX_OUTPUT_TOKENS", fileConfig.llm?.maxOutputTokens ?? 8000),
1412
1484
  timeoutMs: envNum("MASSA_AI_LLM_TIMEOUT_MS", fileConfig.llm?.timeoutMs ?? 90000),
1413
- disableThink: envBool("MASSA_AI_LLM_DISABLE_THINK", fileConfig.llm?.disableThink ?? true)
1485
+ disableThink: envBool("MASSA_AI_LLM_DISABLE_THINK", fileConfig.llm?.disableThink ?? true),
1486
+ contextWindow: fileConfig.llm?.contextWindow ?? INFERENCE_ROLE_DEFAULTS.instruct.contextWindow,
1487
+ codeContextWindow: fileConfig.llm?.codeContextWindow ?? INFERENCE_ROLE_DEFAULTS.coding.contextWindow,
1488
+ codeTemperature: envNum("MASSA_AI_LLM_CODE_TEMPERATURE", fileConfig.llm?.codeTemperature ?? INFERENCE_ROLE_DEFAULTS.coding.temperature)
1414
1489
  },
1415
1490
  memory: {
1416
1491
  decay: {
@@ -9346,7 +9421,7 @@ var require_ignore = __commonJS((exports, module) => {
9346
9421
  var REGEX_REPLACE_LEADING_EXCAPED_HASH = /^\\#/;
9347
9422
  var REGEX_SPLITALL_CRLF = /\r?\n/g;
9348
9423
  var REGEX_TEST_INVALID_PATH = /^\.*\/|^\.+$/;
9349
- var SLASH = "/";
9424
+ var SLASH2 = "/";
9350
9425
  var TMP_KEY_IGNORE = "node-ignore";
9351
9426
  if (typeof Symbol !== "undefined") {
9352
9427
  TMP_KEY_IGNORE = Symbol.for("node-ignore");
@@ -9557,13 +9632,13 @@ var require_ignore = __commonJS((exports, module) => {
9557
9632
  return cache[path16];
9558
9633
  }
9559
9634
  if (!slices) {
9560
- slices = path16.split(SLASH);
9635
+ slices = path16.split(SLASH2);
9561
9636
  }
9562
9637
  slices.pop();
9563
9638
  if (!slices.length) {
9564
9639
  return cache[path16] = this._testOne(path16, checkUnignored);
9565
9640
  }
9566
- const parent = this._t(slices.join(SLASH) + SLASH, cache, checkUnignored, slices);
9641
+ const parent = this._t(slices.join(SLASH2) + SLASH2, cache, checkUnignored, slices);
9567
9642
  return cache[path16] = parent.ignored ? parent : this._testOne(path16, checkUnignored);
9568
9643
  }
9569
9644
  ignores(path16) {
@@ -52395,20 +52470,26 @@ function isLlmEnabled() {
52395
52470
  function _setLlmEnabledForTesting(flag) {
52396
52471
  testEnabledOverride = flag;
52397
52472
  }
52398
- function getLlmConfig(opts) {
52399
- const cfg = config.get("llm");
52400
- const role = opts?.modelRole ?? "instruct";
52401
- const model = role === "code" ? cfg?.codeModel ?? cfg?.model ?? DEFAULT_LLM_MODEL : cfg?.model ?? DEFAULT_LLM_MODEL;
52473
+ function _resolveLlmConfig(cfg, role, baseUrlOverride) {
52474
+ const baseUrl = baseUrlOverride ?? cfg?.baseUrl ?? INFERENCE_PROVIDERS.ollama.defaultLlmBaseUrl;
52475
+ const spec = resolveInferenceSpec(baseUrl);
52476
+ const model = role === "code" ? cfg?.codeModel ?? spec.defaultModels.coding : cfg?.model ?? spec.defaultModels.instruct;
52477
+ const temperature = role === "code" ? cfg?.codeTemperature ?? INFERENCE_ROLE_DEFAULTS.coding.temperature : cfg?.temperature ?? INFERENCE_ROLE_DEFAULTS.instruct.temperature;
52478
+ const contextWindow = role === "code" ? cfg?.codeContextWindow ?? INFERENCE_ROLE_DEFAULTS.coding.contextWindow : cfg?.contextWindow ?? INFERENCE_ROLE_DEFAULTS.instruct.contextWindow;
52402
52479
  return {
52403
- baseUrl: testBaseUrlOverride ?? cfg?.baseUrl ?? "http://localhost:11434/v1",
52404
- apiKey: cfg?.apiKey ?? "ollama",
52480
+ baseUrl,
52481
+ apiKey: cfg?.apiKey ?? spec.id,
52405
52482
  model,
52406
- temperature: cfg?.temperature ?? 0.2,
52483
+ temperature,
52484
+ contextWindow,
52407
52485
  maxOutputTokens: cfg?.maxOutputTokens ?? 8000,
52408
52486
  timeoutMs: cfg?.timeoutMs ?? 90000,
52409
- disableThink: cfg?.disableThink ?? true
52487
+ disableThink: cfg?.disableThink ?? spec.injectsDisableThink
52410
52488
  };
52411
52489
  }
52490
+ function getLlmConfig(opts) {
52491
+ return _resolveLlmConfig(config.get("llm"), opts?.modelRole ?? "instruct", testBaseUrlOverride);
52492
+ }
52412
52493
  function hostPort(url2) {
52413
52494
  try {
52414
52495
  const u = new URL(url2);
@@ -52452,12 +52533,34 @@ function _wrapFetchDisableThink(baseFetch) {
52452
52533
  };
52453
52534
  return wrapped;
52454
52535
  }
52536
+ function _wrapFetchContextWindow(baseFetch, contextWindow) {
52537
+ const wrapped = async (input, init) => {
52538
+ try {
52539
+ if (init?.body && typeof init.body === "string") {
52540
+ const parsed = JSON.parse(init.body);
52541
+ if (parsed && typeof parsed === "object") {
52542
+ parsed.options = { ...parsed.options, num_ctx: contextWindow };
52543
+ init = { ...init, body: JSON.stringify(parsed) };
52544
+ }
52545
+ }
52546
+ } catch {}
52547
+ return baseFetch(input, init);
52548
+ };
52549
+ return wrapped;
52550
+ }
52455
52551
  function buildProvider(llm) {
52456
52552
  const spec = resolveInferenceSpec(llm.baseUrl);
52553
+ let fetchImpl;
52554
+ if (spec.appliesContextPerRequest) {
52555
+ fetchImpl = _wrapFetchContextWindow(fetchImpl ?? globalThis.fetch, llm.contextWindow);
52556
+ }
52557
+ if (llm.disableThink && spec.injectsDisableThink) {
52558
+ fetchImpl = _wrapFetchDisableThink(fetchImpl ?? globalThis.fetch);
52559
+ }
52457
52560
  const openai2 = createOpenAI({
52458
52561
  baseURL: llm.baseUrl,
52459
52562
  apiKey: llm.apiKey,
52460
- ...llm.disableThink && spec.injectsDisableThink ? { fetch: _wrapFetchDisableThink(globalThis.fetch) } : {}
52563
+ ...fetchImpl ? { fetch: fetchImpl } : {}
52461
52564
  });
52462
52565
  return spec.requiresChatCompletionsApi ? openai2.chat(llm.model) : openai2(llm.model);
52463
52566
  }
@@ -95205,6 +95308,9 @@ var init_local_transformers = __esm(() => {
95205
95308
  });
95206
95309
 
95207
95310
  // ../../packages/core/dist/services/embeddings/provider.js
95311
+ function _resolveEmbedContextWindow(embeddingConfig) {
95312
+ return parsePositiveIntEnv(process.env.OLLAMA_EMBEDDING_NUM_CTX, embeddingConfig?.contextWindow ?? INFERENCE_ROLE_DEFAULTS.embedding.contextWindow);
95313
+ }
95208
95314
  function sleep(ms) {
95209
95315
  return new Promise((resolve4) => setTimeout(resolve4, ms));
95210
95316
  }
@@ -95247,7 +95353,7 @@ function createProvider(config3, providerId) {
95247
95353
  }
95248
95354
  return new AISDKEmbeddingProvider(config3, providerId);
95249
95355
  }
95250
- var OLLAMA_EMBED_NUM_CTX, DimensionMismatchError, AISDKEmbeddingProvider;
95356
+ var DimensionMismatchError, AISDKEmbeddingProvider;
95251
95357
  var init_provider = __esm(() => {
95252
95358
  init_dist6();
95253
95359
  init_dist7();
@@ -95259,8 +95365,8 @@ var init_provider = __esm(() => {
95259
95365
  init_rate_limiter2();
95260
95366
  init_dist();
95261
95367
  init_config();
95368
+ init_inference_providers();
95262
95369
  init_local_transformers();
95263
- OLLAMA_EMBED_NUM_CTX = parsePositiveIntEnv(process.env.OLLAMA_EMBEDDING_NUM_CTX, 8192);
95264
95370
  DimensionMismatchError = class DimensionMismatchError extends Error {
95265
95371
  providerId;
95266
95372
  expected;
@@ -95422,7 +95528,7 @@ var init_provider = __esm(() => {
95422
95528
  const response = await this.ollamaFetch("/api/embed", {
95423
95529
  model: this.model,
95424
95530
  input: inputText,
95425
- options: { num_ctx: OLLAMA_EMBED_NUM_CTX }
95531
+ options: { num_ctx: _resolveEmbedContextWindow(loadConfigSafe().embedding) }
95426
95532
  });
95427
95533
  if (!response.ok) {
95428
95534
  throw new Error(`Ollama API error: ${response.status} ${response.statusText}`);
@@ -95513,7 +95619,7 @@ var init_provider = __esm(() => {
95513
95619
  const response = await this.ollamaFetch("/api/embed", {
95514
95620
  model: this.model,
95515
95621
  input: texts.map((t) => this.sanitizeText(this.truncateText(t))),
95516
- options: { num_ctx: OLLAMA_EMBED_NUM_CTX }
95622
+ options: { num_ctx: _resolveEmbedContextWindow(loadConfigSafe().embedding) }
95517
95623
  });
95518
95624
  if (!response.ok) {
95519
95625
  throw new Error(`Ollama batch API error: ${response.status} ${response.statusText}`);
@@ -108159,7 +108265,7 @@ var init_config2 = __esm(() => {
108159
108265
  })(),
108160
108266
  ollama: (() => {
108161
108267
  const file2 = fileFor("ollama");
108162
- const model = process.env.OLLAMA_EMBEDDING_MODEL || file2?.model || "qwen3-embedding:4b";
108268
+ const model = process.env.OLLAMA_EMBEDDING_MODEL || file2?.model || INFERENCE_PROVIDERS.ollama.defaultModels.embedding;
108163
108269
  const rawEnvDimensions = Number(process.env.OLLAMA_EMBEDDING_DIMENSIONS);
108164
108270
  const envDimensions = Number.isInteger(rawEnvDimensions) && rawEnvDimensions > 0 ? rawEnvDimensions : undefined;
108165
108271
  const resolvedDimensions = resolveEmbeddingDimensions(model, file2?.dimensions, envDimensions);
@@ -108265,7 +108371,7 @@ var init_config2 = __esm(() => {
108265
108371
  })(),
108266
108372
  lmstudio: (() => {
108267
108373
  const file2 = fileFor("lmstudio");
108268
- const model = process.env.LMSTUDIO_EMBEDDING_MODEL || file2?.model || "text-embedding-nomic-embed-text-v1.5";
108374
+ const model = process.env.LMSTUDIO_EMBEDDING_MODEL || file2?.model || INFERENCE_PROVIDERS.lmstudio.defaultModels.embedding;
108269
108375
  return {
108270
108376
  provider: "custom",
108271
108377
  model,
@@ -110617,6 +110723,12 @@ var init_base_vector_store = __esm(() => {
110617
110723
  });
110618
110724
 
110619
110725
  // ../../packages/core/dist/data/vector/postgres-vector-store.js
110726
+ function _resolveEmbedBatchSize(embeddingConfig) {
110727
+ const providerId = embeddingConfig?.provider;
110728
+ const spec = providerId && LOCAL_INFERENCE_IDS.includes(providerId) ? INFERENCE_PROVIDERS[providerId] : INFERENCE_PROVIDERS.ollama;
110729
+ return embeddingConfig?.batchSize ?? spec.embedBatchSize;
110730
+ }
110731
+
110620
110732
  class PostgresVectorCollection {
110621
110733
  pool;
110622
110734
  name;
@@ -110729,6 +110841,8 @@ var init_postgres_vector_store = __esm(() => {
110729
110841
  init_base_vector_store();
110730
110842
  init_dist();
110731
110843
  init_dist();
110844
+ init_config();
110845
+ init_inference_providers();
110732
110846
  init_identity_guard_installer();
110733
110847
  PostgresVectorStore = class PostgresVectorStore extends BaseVectorStore {
110734
110848
  pool = null;
@@ -110954,7 +111068,7 @@ var init_postgres_vector_store = __esm(() => {
110954
111068
  if (documents.length === 0)
110955
111069
  return;
110956
111070
  const pool = await this.ensureInitialized();
110957
- const EMBED_SUB_BATCH_SIZE = 8;
111071
+ const EMBED_SUB_BATCH_SIZE = _resolveEmbedBatchSize(loadConfigSafe().embedding);
110958
111072
  let totalInserted = 0;
110959
111073
  let totalFailed = 0;
110960
111074
  for (let i = 0;i < documents.length; i += EMBED_SUB_BATCH_SIZE) {
@@ -128256,6 +128370,7 @@ class PgObservationStore {
128256
128370
  mirror = new Map;
128257
128371
  hydrated = false;
128258
128372
  hydrating = null;
128373
+ inflight = new Map;
128259
128374
  hydrateFailedAt = 0;
128260
128375
  static HYDRATE_RETRY_MS = 30000;
128261
128376
  getClient() {
@@ -128307,46 +128422,53 @@ class PgObservationStore {
128307
128422
  const cachedCanonical = getProjectIdentityAliasResolver().resolveCached(obs.projectId);
128308
128423
  this.mirror.set(obs.id, cachedCanonical && cachedCanonical !== obs.projectId ? { ...obs, projectId: cachedCanonical } : obs);
128309
128424
  this.ensureHydrated();
128310
- (async () => {
128311
- try {
128312
- const prisma2 = this.getClient();
128313
- const canonicalProjectId = await getProjectIdentityAliasResolver().resolve(obs.projectId);
128314
- if (canonicalProjectId !== obs.projectId) {
128315
- this.mirror.set(obs.id, { ...obs, projectId: canonicalProjectId });
128316
- }
128317
- await prisma2.$executeRaw`
128318
- INSERT INTO observations (
128319
- id, project_id, session_id, source, category, payload_json, importance, created_at, agent_id, attribution_source
128320
- ) VALUES (
128321
- ${obs.id},
128322
- ${canonicalProjectId},
128323
- ${obs.sessionId},
128324
- ${obs.source},
128325
- ${obs.category ?? null},
128326
- ${obs.payloadJson},
128327
- ${obs.importance},
128328
- ${obs.createdAt}::bigint,
128329
- ${obs.agentId ?? null},
128330
- ${obs.attributionSource ?? null}
128331
- )
128332
- ON CONFLICT (id) DO UPDATE SET
128333
- project_id = EXCLUDED.project_id,
128334
- session_id = EXCLUDED.session_id,
128335
- source = EXCLUDED.source,
128336
- category = EXCLUDED.category,
128337
- payload_json = EXCLUDED.payload_json,
128338
- importance = EXCLUDED.importance,
128339
- created_at = EXCLUDED.created_at,
128340
- agent_id = EXCLUDED.agent_id,
128341
- attribution_source = EXCLUDED.attribution_source
128342
- `;
128343
- } catch (e) {
128344
- logger.warn("PgObservationStore.insert failed (best-effort)", {
128345
- id: obs.id,
128346
- error: e.message
128347
- });
128425
+ this.chainWrite(obs.id, async () => {
128426
+ const prisma2 = this.getClient();
128427
+ const canonicalProjectId = await getProjectIdentityAliasResolver().resolve(obs.projectId);
128428
+ if (canonicalProjectId !== obs.projectId) {
128429
+ this.mirror.set(obs.id, { ...obs, projectId: canonicalProjectId });
128348
128430
  }
128349
- })();
128431
+ await prisma2.$executeRaw`
128432
+ INSERT INTO observations (
128433
+ id, project_id, session_id, source, category, payload_json, importance, created_at, agent_id, attribution_source
128434
+ ) VALUES (
128435
+ ${obs.id},
128436
+ ${canonicalProjectId},
128437
+ ${obs.sessionId},
128438
+ ${obs.source},
128439
+ ${obs.category ?? null},
128440
+ ${obs.payloadJson},
128441
+ ${obs.importance},
128442
+ ${obs.createdAt}::bigint,
128443
+ ${obs.agentId ?? null},
128444
+ ${obs.attributionSource ?? null}
128445
+ )
128446
+ ON CONFLICT (id) DO UPDATE SET
128447
+ project_id = EXCLUDED.project_id,
128448
+ session_id = EXCLUDED.session_id,
128449
+ source = EXCLUDED.source,
128450
+ category = EXCLUDED.category,
128451
+ payload_json = EXCLUDED.payload_json,
128452
+ importance = EXCLUDED.importance,
128453
+ created_at = EXCLUDED.created_at,
128454
+ agent_id = EXCLUDED.agent_id,
128455
+ attribution_source = EXCLUDED.attribution_source
128456
+ `;
128457
+ });
128458
+ }
128459
+ chainWrite(key, fn) {
128460
+ const prev = this.inflight.get(key) ?? Promise.resolve();
128461
+ const next = prev.then(fn).catch((e) => {
128462
+ logger.warn("PgObservationStore.insert failed (best-effort)", {
128463
+ id: key,
128464
+ error: e.message
128465
+ });
128466
+ });
128467
+ this.inflight.set(key, next);
128468
+ next.then(() => {
128469
+ if (this.inflight.get(key) === next)
128470
+ this.inflight.delete(key);
128471
+ });
128350
128472
  }
128351
128473
  listRecent(projectId, limit) {
128352
128474
  this.ensureHydrated();
@@ -128373,6 +128495,9 @@ class PgObservationStore {
128373
128495
  await this.ensureHydrated();
128374
128496
  }
128375
128497
  async __drain() {
128498
+ const pending = Array.from(this.inflight.values());
128499
+ if (pending.length > 0)
128500
+ await Promise.allSettled(pending);
128376
128501
  await new Promise((r) => setTimeout(r, 10));
128377
128502
  }
128378
128503
  }
@@ -154152,7 +154277,7 @@ Examples:
154152
154277
  massa-ai-config init
154153
154278
  massa-ai-config init --lmstudio
154154
154279
  massa-ai-config init --mistral your-api-key
154155
- massa-ai-config use ollama --model qwen3-embedding:4b
154280
+ massa-ai-config use ollama --model qwen3-embedding:0.6b
154156
154281
  massa-ai-config use lmstudio
154157
154282
  massa-ai-config use mistral --api-key your-key
154158
154283
  massa-ai-config set embedding.dimensions 1024
@@ -154234,7 +154359,7 @@ async function runCli(argv) {
154234
154359
  console.log("\u2713 Configured for OpenAI embeddings");
154235
154360
  } else if (options.lmstudio) {
154236
154361
  const config3 = loadConfig();
154237
- const model = "text-embedding-nomic-embed-text-v1.5";
154362
+ const model = INFERENCE_PROVIDERS.lmstudio.defaultModels.embedding;
154238
154363
  config3.embedding = {
154239
154364
  provider: "lmstudio",
154240
154365
  model,
@@ -154242,6 +154367,8 @@ async function runCli(argv) {
154242
154367
  dimensions: INFERENCE_PROVIDERS.lmstudio.knownDimensions[model] ?? 768
154243
154368
  };
154244
154369
  config3.llm.baseUrl = INFERENCE_PROVIDERS.lmstudio.defaultLlmBaseUrl;
154370
+ config3.llm.model = INFERENCE_PROVIDERS.lmstudio.defaultModels.instruct;
154371
+ config3.llm.codeModel = INFERENCE_PROVIDERS.lmstudio.defaultModels.coding;
154245
154372
  saveConfig(config3);
154246
154373
  console.log("\u2713 Configured for LM Studio (local) embeddings");
154247
154374
  } else {
@@ -154294,21 +154421,29 @@ Using defaults:`);
154294
154421
  }
154295
154422
  const config3 = loadConfig();
154296
154423
  if (provider === "ollama") {
154424
+ const model = options.model || INFERENCE_PROVIDERS.ollama.defaultModels.embedding;
154425
+ const urls = deriveInferenceBaseUrls("ollama", options["base-url"]);
154297
154426
  config3.embedding = {
154298
154427
  provider: "ollama",
154299
- model: options.model || "qwen3-embedding:4b",
154300
- baseURL: options["base-url"] || "http://localhost:11434",
154301
- dimensions: 2560
154428
+ model,
154429
+ baseURL: urls.embeddingBaseUrl,
154430
+ dimensions: knownEmbeddingDimensions(model) ?? 768
154302
154431
  };
154432
+ config3.llm.baseUrl = urls.llmBaseUrl;
154433
+ config3.llm.model = INFERENCE_PROVIDERS.ollama.defaultModels.instruct;
154434
+ config3.llm.codeModel = INFERENCE_PROVIDERS.ollama.defaultModels.coding;
154303
154435
  } else if (provider === "lmstudio") {
154304
- const model = options.model || "text-embedding-nomic-embed-text-v1.5";
154436
+ const model = options.model || INFERENCE_PROVIDERS.lmstudio.defaultModels.embedding;
154437
+ const urls = deriveInferenceBaseUrls("lmstudio", options["base-url"]);
154305
154438
  config3.embedding = {
154306
154439
  provider: "lmstudio",
154307
154440
  model,
154308
- baseURL: options["base-url"] || INFERENCE_PROVIDERS.lmstudio.defaultEmbeddingBaseUrl,
154441
+ baseURL: urls.embeddingBaseUrl,
154309
154442
  dimensions: INFERENCE_PROVIDERS.lmstudio.knownDimensions[model] ?? 768
154310
154443
  };
154311
- config3.llm.baseUrl = options["base-url"] || INFERENCE_PROVIDERS.lmstudio.defaultLlmBaseUrl;
154444
+ config3.llm.baseUrl = urls.llmBaseUrl;
154445
+ config3.llm.model = INFERENCE_PROVIDERS.lmstudio.defaultModels.instruct;
154446
+ config3.llm.codeModel = INFERENCE_PROVIDERS.lmstudio.defaultModels.coding;
154312
154447
  } else if (provider === "mistral") {
154313
154448
  if (!options["api-key"]) {
154314
154449
  console.error("Error: --api-key required for Mistral");
package/dist/index.js CHANGED
@@ -25441,10 +25441,33 @@ function parseLmStudioModelList(body) {
25441
25441
  function inferenceProviderList() {
25442
25442
  return LOCAL_INFERENCE_IDS.map((id) => INFERENCE_PROVIDERS[id]);
25443
25443
  }
25444
- var LOCAL_INFERENCE_IDS, INFERENCE_PROVIDERS;
25444
+ function deriveInferenceBaseUrls(providerId, explicitBaseUrl) {
25445
+ const spec = INFERENCE_PROVIDERS[providerId];
25446
+ if (!explicitBaseUrl) {
25447
+ return {
25448
+ embeddingBaseUrl: spec.defaultEmbeddingBaseUrl,
25449
+ llmBaseUrl: spec.defaultLlmBaseUrl
25450
+ };
25451
+ }
25452
+ let end = explicitBaseUrl.length;
25453
+ while (end > 0 && explicitBaseUrl.charCodeAt(end - 1) === SLASH)
25454
+ end--;
25455
+ const base = explicitBaseUrl.slice(0, end);
25456
+ const suffix = spec.defaultLlmBaseUrl.startsWith(spec.defaultEmbeddingBaseUrl) ? spec.defaultLlmBaseUrl.slice(spec.defaultEmbeddingBaseUrl.length) : "";
25457
+ return {
25458
+ embeddingBaseUrl: base,
25459
+ llmBaseUrl: `${base}${suffix}`
25460
+ };
25461
+ }
25462
+ var LOCAL_INFERENCE_IDS, INFERENCE_ROLE_DEFAULTS, INFERENCE_PROVIDERS, SLASH = 47;
25445
25463
  var init_inference_providers = __esm(() => {
25446
25464
  init_embedding_dimensions();
25447
25465
  LOCAL_INFERENCE_IDS = ["ollama", "lmstudio"];
25466
+ INFERENCE_ROLE_DEFAULTS = {
25467
+ embedding: { contextWindow: 8192 },
25468
+ instruct: { contextWindow: 16384, temperature: 0.2 },
25469
+ coding: { contextWindow: 32768, temperature: 0 }
25470
+ };
25448
25471
  INFERENCE_PROVIDERS = {
25449
25472
  ollama: {
25450
25473
  id: "ollama",
@@ -25456,6 +25479,13 @@ var init_inference_providers = __esm(() => {
25456
25479
  dimensions: "OLLAMA_EMBEDDING_DIMENSIONS"
25457
25480
  },
25458
25481
  knownDimensions: KNOWN_EMBEDDING_DIMENSIONS,
25482
+ defaultModels: {
25483
+ embedding: "qwen3-embedding:0.6b",
25484
+ instruct: "qwen3-vl:8b",
25485
+ coding: "qwen2.5-coder:7b"
25486
+ },
25487
+ appliesContextPerRequest: true,
25488
+ embedBatchSize: 64,
25459
25489
  supportsOllamaVersionProbe: true,
25460
25490
  injectsDisableThink: true,
25461
25491
  requiresChatCompletionsApi: false,
@@ -25471,8 +25501,36 @@ var init_inference_providers = __esm(() => {
25471
25501
  dimensions: "LMSTUDIO_EMBEDDING_DIMENSIONS"
25472
25502
  },
25473
25503
  knownDimensions: {
25474
- "text-embedding-nomic-embed-text-v1.5": 768
25504
+ "text-embedding-nomic-embed-text-v1.5": 768,
25505
+ "text-embedding-qwen3-embedding-0.6b": 1024,
25506
+ "qwen3-embedding-0.6b-dwq": 1024
25507
+ },
25508
+ defaultModels: {
25509
+ embedding: "text-embedding-qwen3-embedding-0.6b",
25510
+ instruct: "qwen3-vl-8b-instruct",
25511
+ coding: "qwen2.5-coder-7b-instruct"
25512
+ },
25513
+ mlxModels: {
25514
+ embedding: {
25515
+ repo: "mlx-community/Qwen3-Embedding-0.6B-4bit-DWQ",
25516
+ model: "qwen3-embedding-0.6b-dwq"
25517
+ },
25518
+ instruct: {
25519
+ repo: "mlx-community/Qwen3-VL-8B-Instruct-4bit",
25520
+ model: "qwen3-vl-8b-instruct"
25521
+ },
25522
+ coding: {
25523
+ repo: "mlx-community/Qwen2.5-Coder-7B-Instruct-4bit",
25524
+ model: "qwen2.5-coder-7b-instruct"
25525
+ }
25526
+ },
25527
+ ggufRepos: {
25528
+ embedding: "Qwen/Qwen3-Embedding-0.6B-GGUF",
25529
+ instruct: "lmstudio-community/Qwen3-VL-8B-Instruct-GGUF",
25530
+ coding: "lmstudio-community/Qwen2.5-Coder-7B-Instruct-GGUF"
25475
25531
  },
25532
+ appliesContextPerRequest: false,
25533
+ embedBatchSize: 64,
25476
25534
  supportsOllamaVersionProbe: false,
25477
25535
  injectsDisableThink: false,
25478
25536
  requiresChatCompletionsApi: true,
@@ -25487,6 +25545,7 @@ var API_PROVIDER_IDS, EMBEDDING_PROVIDER_IDS, SCHEDULER_JOB_KINDS, MAX_MATCH_WOR
25487
25545
  var init_massa_ai_config = __esm(() => {
25488
25546
  init_xdg();
25489
25547
  init_inference_providers();
25548
+ init_embedding_dimensions();
25490
25549
  API_PROVIDER_IDS = ["mistral", "openai", "google", "cohere"];
25491
25550
  EMBEDDING_PROVIDER_IDS = [
25492
25551
  ...LOCAL_INFERENCE_IDS,
@@ -25553,9 +25612,9 @@ var init_massa_ai_config = __esm(() => {
25553
25612
  },
25554
25613
  embedding: {
25555
25614
  provider: "ollama",
25556
- model: "qwen3-embedding:4b",
25615
+ model: INFERENCE_PROVIDERS.ollama.defaultModels.embedding,
25557
25616
  baseURL: "http://localhost:11434",
25558
- dimensions: 2560
25617
+ dimensions: knownEmbeddingDimensions(INFERENCE_PROVIDERS.ollama.defaultModels.embedding) ?? 768
25559
25618
  },
25560
25619
  compression: {
25561
25620
  defaultStrategy: "code_structure",
@@ -25594,12 +25653,15 @@ var init_massa_ai_config = __esm(() => {
25594
25653
  enabled: false,
25595
25654
  baseUrl: "http://localhost:11434/v1",
25596
25655
  apiKey: "ollama",
25597
- model: "qwen2.5:7b-instruct",
25598
- codeModel: "qwen2.5-coder:7b",
25656
+ model: INFERENCE_PROVIDERS.ollama.defaultModels.instruct,
25657
+ codeModel: INFERENCE_PROVIDERS.ollama.defaultModels.coding,
25599
25658
  temperature: 0.2,
25600
25659
  maxOutputTokens: 8000,
25601
25660
  timeoutMs: 90000,
25602
- disableThink: true
25661
+ disableThink: true,
25662
+ contextWindow: INFERENCE_ROLE_DEFAULTS.instruct.contextWindow,
25663
+ codeContextWindow: INFERENCE_ROLE_DEFAULTS.coding.contextWindow,
25664
+ codeTemperature: INFERENCE_ROLE_DEFAULTS.coding.temperature
25603
25665
  },
25604
25666
  memory: {
25605
25667
  decay: {
@@ -26154,6 +26216,13 @@ function getGlobalDataDir() {
26154
26216
  return fileConfig.dataDir;
26155
26217
  return path4.join(getConfigDir(), "data");
26156
26218
  }
26219
+ function activeInferenceProviderId() {
26220
+ const providerId = fileConfig.embedding?.provider;
26221
+ if (providerId && LOCAL_INFERENCE_IDS.includes(providerId)) {
26222
+ return providerId;
26223
+ }
26224
+ return "ollama";
26225
+ }
26157
26226
 
26158
26227
  class Config {
26159
26228
  config;
@@ -26290,11 +26359,12 @@ class Config {
26290
26359
  this.config[key] = value;
26291
26360
  }
26292
26361
  }
26293
- var DEFAULT_LLM_MODEL = "qwen2.5:7b-instruct", DEFAULT_LLM_CODE_MODEL = "qwen2.5-coder:7b", SCHEDULER_JOB_ENV, DEFAULT_ALLOWED_EXTENSIONS, fileConfig, fileCacheL1Bytes, fileCacheL2Bytes, resolvedDataDir, defaultConfig, config2;
26362
+ var SCHEDULER_JOB_ENV, DEFAULT_ALLOWED_EXTENSIONS, fileConfig, DEFAULT_LLM_MODEL, DEFAULT_LLM_CODE_MODEL, fileCacheL1Bytes, fileCacheL2Bytes, resolvedDataDir, defaultConfig, config2;
26294
26363
  var init_config = __esm(() => {
26295
26364
  init_env();
26296
26365
  init_config_loader();
26297
26366
  init_massa_ai_config();
26367
+ init_inference_providers();
26298
26368
  init_massa_ai_config();
26299
26369
  init_massa_ai_config();
26300
26370
  init_config_loader();
@@ -26365,6 +26435,8 @@ var init_config = __esm(() => {
26365
26435
  ".hs"
26366
26436
  ];
26367
26437
  fileConfig = loadConfigSafe();
26438
+ DEFAULT_LLM_MODEL = INFERENCE_PROVIDERS[activeInferenceProviderId()].defaultModels.instruct;
26439
+ DEFAULT_LLM_CODE_MODEL = INFERENCE_PROVIDERS[activeInferenceProviderId()].defaultModels.coding;
26368
26440
  fileCacheL1Bytes = fileConfig.cache?.l1MaxSizeMB ? fileConfig.cache.l1MaxSizeMB * 1024 * 1024 : undefined;
26369
26441
  fileCacheL2Bytes = fileConfig.cache?.l2MaxSizeMB ? fileConfig.cache.l2MaxSizeMB * 1024 * 1024 : undefined;
26370
26442
  resolvedDataDir = getGlobalDataDir();
@@ -26407,7 +26479,10 @@ var init_config = __esm(() => {
26407
26479
  temperature: envNum("MASSA_AI_LLM_TEMPERATURE", fileConfig.llm?.temperature ?? 0.2),
26408
26480
  maxOutputTokens: envNum("MASSA_AI_LLM_MAX_OUTPUT_TOKENS", fileConfig.llm?.maxOutputTokens ?? 8000),
26409
26481
  timeoutMs: envNum("MASSA_AI_LLM_TIMEOUT_MS", fileConfig.llm?.timeoutMs ?? 90000),
26410
- disableThink: envBool("MASSA_AI_LLM_DISABLE_THINK", fileConfig.llm?.disableThink ?? true)
26482
+ disableThink: envBool("MASSA_AI_LLM_DISABLE_THINK", fileConfig.llm?.disableThink ?? true),
26483
+ contextWindow: fileConfig.llm?.contextWindow ?? INFERENCE_ROLE_DEFAULTS.instruct.contextWindow,
26484
+ codeContextWindow: fileConfig.llm?.codeContextWindow ?? INFERENCE_ROLE_DEFAULTS.coding.contextWindow,
26485
+ codeTemperature: envNum("MASSA_AI_LLM_CODE_TEMPERATURE", fileConfig.llm?.codeTemperature ?? INFERENCE_ROLE_DEFAULTS.coding.temperature)
26411
26486
  },
26412
26487
  memory: {
26413
26488
  decay: {
@@ -34343,7 +34418,7 @@ var require_ignore = __commonJS((exports, module) => {
34343
34418
  var REGEX_REPLACE_LEADING_EXCAPED_HASH = /^\\#/;
34344
34419
  var REGEX_SPLITALL_CRLF = /\r?\n/g;
34345
34420
  var REGEX_TEST_INVALID_PATH = /^\.*\/|^\.+$/;
34346
- var SLASH = "/";
34421
+ var SLASH2 = "/";
34347
34422
  var TMP_KEY_IGNORE = "node-ignore";
34348
34423
  if (typeof Symbol !== "undefined") {
34349
34424
  TMP_KEY_IGNORE = Symbol.for("node-ignore");
@@ -34554,13 +34629,13 @@ var require_ignore = __commonJS((exports, module) => {
34554
34629
  return cache[path16];
34555
34630
  }
34556
34631
  if (!slices) {
34557
- slices = path16.split(SLASH);
34632
+ slices = path16.split(SLASH2);
34558
34633
  }
34559
34634
  slices.pop();
34560
34635
  if (!slices.length) {
34561
34636
  return cache[path16] = this._testOne(path16, checkUnignored);
34562
34637
  }
34563
- const parent = this._t(slices.join(SLASH) + SLASH, cache, checkUnignored, slices);
34638
+ const parent = this._t(slices.join(SLASH2) + SLASH2, cache, checkUnignored, slices);
34564
34639
  return cache[path16] = parent.ignored ? parent : this._testOne(path16, checkUnignored);
34565
34640
  }
34566
34641
  ignores(path16) {
@@ -58954,20 +59029,26 @@ function isLlmEnabled() {
58954
59029
  function _setLlmEnabledForTesting(flag) {
58955
59030
  testEnabledOverride = flag;
58956
59031
  }
58957
- function getLlmConfig(opts) {
58958
- const cfg = config2.get("llm");
58959
- const role = opts?.modelRole ?? "instruct";
58960
- const model = role === "code" ? cfg?.codeModel ?? cfg?.model ?? DEFAULT_LLM_MODEL : cfg?.model ?? DEFAULT_LLM_MODEL;
59032
+ function _resolveLlmConfig(cfg, role, baseUrlOverride) {
59033
+ const baseUrl = baseUrlOverride ?? cfg?.baseUrl ?? INFERENCE_PROVIDERS.ollama.defaultLlmBaseUrl;
59034
+ const spec = resolveInferenceSpec(baseUrl);
59035
+ const model = role === "code" ? cfg?.codeModel ?? spec.defaultModels.coding : cfg?.model ?? spec.defaultModels.instruct;
59036
+ const temperature = role === "code" ? cfg?.codeTemperature ?? INFERENCE_ROLE_DEFAULTS.coding.temperature : cfg?.temperature ?? INFERENCE_ROLE_DEFAULTS.instruct.temperature;
59037
+ const contextWindow = role === "code" ? cfg?.codeContextWindow ?? INFERENCE_ROLE_DEFAULTS.coding.contextWindow : cfg?.contextWindow ?? INFERENCE_ROLE_DEFAULTS.instruct.contextWindow;
58961
59038
  return {
58962
- baseUrl: testBaseUrlOverride ?? cfg?.baseUrl ?? "http://localhost:11434/v1",
58963
- apiKey: cfg?.apiKey ?? "ollama",
59039
+ baseUrl,
59040
+ apiKey: cfg?.apiKey ?? spec.id,
58964
59041
  model,
58965
- temperature: cfg?.temperature ?? 0.2,
59042
+ temperature,
59043
+ contextWindow,
58966
59044
  maxOutputTokens: cfg?.maxOutputTokens ?? 8000,
58967
59045
  timeoutMs: cfg?.timeoutMs ?? 90000,
58968
- disableThink: cfg?.disableThink ?? true
59046
+ disableThink: cfg?.disableThink ?? spec.injectsDisableThink
58969
59047
  };
58970
59048
  }
59049
+ function getLlmConfig(opts) {
59050
+ return _resolveLlmConfig(config2.get("llm"), opts?.modelRole ?? "instruct", testBaseUrlOverride);
59051
+ }
58971
59052
  function hostPort(url2) {
58972
59053
  try {
58973
59054
  const u = new URL(url2);
@@ -59011,12 +59092,34 @@ function _wrapFetchDisableThink(baseFetch) {
59011
59092
  };
59012
59093
  return wrapped;
59013
59094
  }
59095
+ function _wrapFetchContextWindow(baseFetch, contextWindow) {
59096
+ const wrapped = async (input, init) => {
59097
+ try {
59098
+ if (init?.body && typeof init.body === "string") {
59099
+ const parsed = JSON.parse(init.body);
59100
+ if (parsed && typeof parsed === "object") {
59101
+ parsed.options = { ...parsed.options, num_ctx: contextWindow };
59102
+ init = { ...init, body: JSON.stringify(parsed) };
59103
+ }
59104
+ }
59105
+ } catch {}
59106
+ return baseFetch(input, init);
59107
+ };
59108
+ return wrapped;
59109
+ }
59014
59110
  function buildProvider(llm) {
59015
59111
  const spec = resolveInferenceSpec(llm.baseUrl);
59112
+ let fetchImpl;
59113
+ if (spec.appliesContextPerRequest) {
59114
+ fetchImpl = _wrapFetchContextWindow(fetchImpl ?? globalThis.fetch, llm.contextWindow);
59115
+ }
59116
+ if (llm.disableThink && spec.injectsDisableThink) {
59117
+ fetchImpl = _wrapFetchDisableThink(fetchImpl ?? globalThis.fetch);
59118
+ }
59016
59119
  const openai2 = createOpenAI({
59017
59120
  baseURL: llm.baseUrl,
59018
59121
  apiKey: llm.apiKey,
59019
- ...llm.disableThink && spec.injectsDisableThink ? { fetch: _wrapFetchDisableThink(globalThis.fetch) } : {}
59122
+ ...fetchImpl ? { fetch: fetchImpl } : {}
59020
59123
  });
59021
59124
  return spec.requiresChatCompletionsApi ? openai2.chat(llm.model) : openai2(llm.model);
59022
59125
  }
@@ -101764,6 +101867,9 @@ var init_local_transformers = __esm(() => {
101764
101867
  });
101765
101868
 
101766
101869
  // ../../packages/core/dist/services/embeddings/provider.js
101870
+ function _resolveEmbedContextWindow(embeddingConfig) {
101871
+ return parsePositiveIntEnv(process.env.OLLAMA_EMBEDDING_NUM_CTX, embeddingConfig?.contextWindow ?? INFERENCE_ROLE_DEFAULTS.embedding.contextWindow);
101872
+ }
101767
101873
  function sleep(ms) {
101768
101874
  return new Promise((resolve4) => setTimeout(resolve4, ms));
101769
101875
  }
@@ -101806,7 +101912,7 @@ function createProvider(config3, providerId) {
101806
101912
  }
101807
101913
  return new AISDKEmbeddingProvider(config3, providerId);
101808
101914
  }
101809
- var OLLAMA_EMBED_NUM_CTX, DimensionMismatchError, AISDKEmbeddingProvider;
101915
+ var DimensionMismatchError, AISDKEmbeddingProvider;
101810
101916
  var init_provider = __esm(() => {
101811
101917
  init_dist6();
101812
101918
  init_dist7();
@@ -101818,8 +101924,8 @@ var init_provider = __esm(() => {
101818
101924
  init_rate_limiter2();
101819
101925
  init_dist();
101820
101926
  init_config();
101927
+ init_inference_providers();
101821
101928
  init_local_transformers();
101822
- OLLAMA_EMBED_NUM_CTX = parsePositiveIntEnv(process.env.OLLAMA_EMBEDDING_NUM_CTX, 8192);
101823
101929
  DimensionMismatchError = class DimensionMismatchError extends Error {
101824
101930
  providerId;
101825
101931
  expected;
@@ -101981,7 +102087,7 @@ var init_provider = __esm(() => {
101981
102087
  const response = await this.ollamaFetch("/api/embed", {
101982
102088
  model: this.model,
101983
102089
  input: inputText,
101984
- options: { num_ctx: OLLAMA_EMBED_NUM_CTX }
102090
+ options: { num_ctx: _resolveEmbedContextWindow(loadConfigSafe().embedding) }
101985
102091
  });
101986
102092
  if (!response.ok) {
101987
102093
  throw new Error(`Ollama API error: ${response.status} ${response.statusText}`);
@@ -102072,7 +102178,7 @@ var init_provider = __esm(() => {
102072
102178
  const response = await this.ollamaFetch("/api/embed", {
102073
102179
  model: this.model,
102074
102180
  input: texts.map((t) => this.sanitizeText(this.truncateText(t))),
102075
- options: { num_ctx: OLLAMA_EMBED_NUM_CTX }
102181
+ options: { num_ctx: _resolveEmbedContextWindow(loadConfigSafe().embedding) }
102076
102182
  });
102077
102183
  if (!response.ok) {
102078
102184
  throw new Error(`Ollama batch API error: ${response.status} ${response.statusText}`);
@@ -114718,7 +114824,7 @@ var init_config2 = __esm(() => {
114718
114824
  })(),
114719
114825
  ollama: (() => {
114720
114826
  const file2 = fileFor("ollama");
114721
- const model = process.env.OLLAMA_EMBEDDING_MODEL || file2?.model || "qwen3-embedding:4b";
114827
+ const model = process.env.OLLAMA_EMBEDDING_MODEL || file2?.model || INFERENCE_PROVIDERS.ollama.defaultModels.embedding;
114722
114828
  const rawEnvDimensions = Number(process.env.OLLAMA_EMBEDDING_DIMENSIONS);
114723
114829
  const envDimensions = Number.isInteger(rawEnvDimensions) && rawEnvDimensions > 0 ? rawEnvDimensions : undefined;
114724
114830
  const resolvedDimensions = resolveEmbeddingDimensions(model, file2?.dimensions, envDimensions);
@@ -114824,7 +114930,7 @@ var init_config2 = __esm(() => {
114824
114930
  })(),
114825
114931
  lmstudio: (() => {
114826
114932
  const file2 = fileFor("lmstudio");
114827
- const model = process.env.LMSTUDIO_EMBEDDING_MODEL || file2?.model || "text-embedding-nomic-embed-text-v1.5";
114933
+ const model = process.env.LMSTUDIO_EMBEDDING_MODEL || file2?.model || INFERENCE_PROVIDERS.lmstudio.defaultModels.embedding;
114828
114934
  return {
114829
114935
  provider: "custom",
114830
114936
  model,
@@ -117176,6 +117282,12 @@ var init_base_vector_store = __esm(() => {
117176
117282
  });
117177
117283
 
117178
117284
  // ../../packages/core/dist/data/vector/postgres-vector-store.js
117285
+ function _resolveEmbedBatchSize(embeddingConfig) {
117286
+ const providerId = embeddingConfig?.provider;
117287
+ const spec = providerId && LOCAL_INFERENCE_IDS.includes(providerId) ? INFERENCE_PROVIDERS[providerId] : INFERENCE_PROVIDERS.ollama;
117288
+ return embeddingConfig?.batchSize ?? spec.embedBatchSize;
117289
+ }
117290
+
117179
117291
  class PostgresVectorCollection {
117180
117292
  pool;
117181
117293
  name;
@@ -117288,6 +117400,8 @@ var init_postgres_vector_store = __esm(() => {
117288
117400
  init_base_vector_store();
117289
117401
  init_dist();
117290
117402
  init_dist();
117403
+ init_config();
117404
+ init_inference_providers();
117291
117405
  init_identity_guard_installer();
117292
117406
  PostgresVectorStore = class PostgresVectorStore extends BaseVectorStore {
117293
117407
  pool = null;
@@ -117513,7 +117627,7 @@ var init_postgres_vector_store = __esm(() => {
117513
117627
  if (documents.length === 0)
117514
117628
  return;
117515
117629
  const pool = await this.ensureInitialized();
117516
- const EMBED_SUB_BATCH_SIZE = 8;
117630
+ const EMBED_SUB_BATCH_SIZE = _resolveEmbedBatchSize(loadConfigSafe().embedding);
117517
117631
  let totalInserted = 0;
117518
117632
  let totalFailed = 0;
117519
117633
  for (let i = 0;i < documents.length; i += EMBED_SUB_BATCH_SIZE) {
@@ -138007,6 +138121,7 @@ class PgObservationStore {
138007
138121
  mirror = new Map;
138008
138122
  hydrated = false;
138009
138123
  hydrating = null;
138124
+ inflight = new Map;
138010
138125
  hydrateFailedAt = 0;
138011
138126
  static HYDRATE_RETRY_MS = 30000;
138012
138127
  getClient() {
@@ -138058,46 +138173,53 @@ class PgObservationStore {
138058
138173
  const cachedCanonical = getProjectIdentityAliasResolver().resolveCached(obs.projectId);
138059
138174
  this.mirror.set(obs.id, cachedCanonical && cachedCanonical !== obs.projectId ? { ...obs, projectId: cachedCanonical } : obs);
138060
138175
  this.ensureHydrated();
138061
- (async () => {
138062
- try {
138063
- const prisma2 = this.getClient();
138064
- const canonicalProjectId = await getProjectIdentityAliasResolver().resolve(obs.projectId);
138065
- if (canonicalProjectId !== obs.projectId) {
138066
- this.mirror.set(obs.id, { ...obs, projectId: canonicalProjectId });
138067
- }
138068
- await prisma2.$executeRaw`
138069
- INSERT INTO observations (
138070
- id, project_id, session_id, source, category, payload_json, importance, created_at, agent_id, attribution_source
138071
- ) VALUES (
138072
- ${obs.id},
138073
- ${canonicalProjectId},
138074
- ${obs.sessionId},
138075
- ${obs.source},
138076
- ${obs.category ?? null},
138077
- ${obs.payloadJson},
138078
- ${obs.importance},
138079
- ${obs.createdAt}::bigint,
138080
- ${obs.agentId ?? null},
138081
- ${obs.attributionSource ?? null}
138082
- )
138083
- ON CONFLICT (id) DO UPDATE SET
138084
- project_id = EXCLUDED.project_id,
138085
- session_id = EXCLUDED.session_id,
138086
- source = EXCLUDED.source,
138087
- category = EXCLUDED.category,
138088
- payload_json = EXCLUDED.payload_json,
138089
- importance = EXCLUDED.importance,
138090
- created_at = EXCLUDED.created_at,
138091
- agent_id = EXCLUDED.agent_id,
138092
- attribution_source = EXCLUDED.attribution_source
138093
- `;
138094
- } catch (e) {
138095
- logger.warn("PgObservationStore.insert failed (best-effort)", {
138096
- id: obs.id,
138097
- error: e.message
138098
- });
138176
+ this.chainWrite(obs.id, async () => {
138177
+ const prisma2 = this.getClient();
138178
+ const canonicalProjectId = await getProjectIdentityAliasResolver().resolve(obs.projectId);
138179
+ if (canonicalProjectId !== obs.projectId) {
138180
+ this.mirror.set(obs.id, { ...obs, projectId: canonicalProjectId });
138099
138181
  }
138100
- })();
138182
+ await prisma2.$executeRaw`
138183
+ INSERT INTO observations (
138184
+ id, project_id, session_id, source, category, payload_json, importance, created_at, agent_id, attribution_source
138185
+ ) VALUES (
138186
+ ${obs.id},
138187
+ ${canonicalProjectId},
138188
+ ${obs.sessionId},
138189
+ ${obs.source},
138190
+ ${obs.category ?? null},
138191
+ ${obs.payloadJson},
138192
+ ${obs.importance},
138193
+ ${obs.createdAt}::bigint,
138194
+ ${obs.agentId ?? null},
138195
+ ${obs.attributionSource ?? null}
138196
+ )
138197
+ ON CONFLICT (id) DO UPDATE SET
138198
+ project_id = EXCLUDED.project_id,
138199
+ session_id = EXCLUDED.session_id,
138200
+ source = EXCLUDED.source,
138201
+ category = EXCLUDED.category,
138202
+ payload_json = EXCLUDED.payload_json,
138203
+ importance = EXCLUDED.importance,
138204
+ created_at = EXCLUDED.created_at,
138205
+ agent_id = EXCLUDED.agent_id,
138206
+ attribution_source = EXCLUDED.attribution_source
138207
+ `;
138208
+ });
138209
+ }
138210
+ chainWrite(key, fn) {
138211
+ const prev = this.inflight.get(key) ?? Promise.resolve();
138212
+ const next = prev.then(fn).catch((e) => {
138213
+ logger.warn("PgObservationStore.insert failed (best-effort)", {
138214
+ id: key,
138215
+ error: e.message
138216
+ });
138217
+ });
138218
+ this.inflight.set(key, next);
138219
+ next.then(() => {
138220
+ if (this.inflight.get(key) === next)
138221
+ this.inflight.delete(key);
138222
+ });
138101
138223
  }
138102
138224
  listRecent(projectId, limit) {
138103
138225
  this.ensureHydrated();
@@ -138124,6 +138246,9 @@ class PgObservationStore {
138124
138246
  await this.ensureHydrated();
138125
138247
  }
138126
138248
  async __drain() {
138249
+ const pending = Array.from(this.inflight.values());
138250
+ if (pending.length > 0)
138251
+ await Promise.allSettled(pending);
138127
138252
  await new Promise((r) => setTimeout(r, 10));
138128
138253
  }
138129
138254
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@massa-ai/mcp-client",
3
- "version": "1.58.0",
3
+ "version": "1.60.0",
4
4
  "description": "massa-ai MCP server - Semantic code search, memory, and context compression via Model Context Protocol",
5
5
  "author": "luizgmassa",
6
6
  "type": "module",
@@ -20,8 +20,8 @@
20
20
  "type-check": "tsc --noEmit"
21
21
  },
22
22
  "dependencies": {
23
- "@massa-ai/core": "^1.58.0",
24
- "@massa-ai/shared": "^1.58.0",
23
+ "@massa-ai/core": "^1.60.0",
24
+ "@massa-ai/shared": "^1.60.0",
25
25
  "@modelcontextprotocol/sdk": "^1.0.0"
26
26
  },
27
27
  "devDependencies": {