@massa-ai/tools-api 1.2.1 → 1.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +136 -56
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -557,7 +557,8 @@ __export(exports_config_loader, {
|
|
|
557
557
|
getConfigPath: () => getConfigPath,
|
|
558
558
|
getConfigForEnv: () => getConfigForEnv,
|
|
559
559
|
getConfigDir: () => getConfigDir,
|
|
560
|
-
configExists: () => configExists
|
|
560
|
+
configExists: () => configExists,
|
|
561
|
+
__resetMigrationForTests: () => __resetMigrationForTests
|
|
561
562
|
});
|
|
562
563
|
import fs from "fs";
|
|
563
564
|
import path3 from "path";
|
|
@@ -627,6 +628,9 @@ function migrateDataDirOnce() {
|
|
|
627
628
|
console.error(`[massa-ai] Data directory migration skipped:`, err);
|
|
628
629
|
}
|
|
629
630
|
}
|
|
631
|
+
function __resetMigrationForTests() {
|
|
632
|
+
migrationAttempted = false;
|
|
633
|
+
}
|
|
630
634
|
function saveConfig(config) {
|
|
631
635
|
if (!fs.existsSync(CONFIG_DIR)) {
|
|
632
636
|
fs.mkdirSync(CONFIG_DIR, { recursive: true });
|
|
@@ -636,7 +640,7 @@ function saveConfig(config) {
|
|
|
636
640
|
function initConfig() {
|
|
637
641
|
if (!fs.existsSync(CONFIG_FILE)) {
|
|
638
642
|
saveConfig(defaultMassaAiConfig);
|
|
639
|
-
console.
|
|
643
|
+
console.error(`Created default config at ${CONFIG_FILE}`);
|
|
640
644
|
}
|
|
641
645
|
}
|
|
642
646
|
function getConfigForEnv() {
|
|
@@ -688,7 +692,7 @@ var import_dotenv, envPath;
|
|
|
688
692
|
var init_env = __esm(() => {
|
|
689
693
|
import_dotenv = __toESM(require_main(), 1);
|
|
690
694
|
envPath = findEnvFile();
|
|
691
|
-
import_dotenv.config({ path: envPath });
|
|
695
|
+
import_dotenv.config({ path: envPath, quiet: true });
|
|
692
696
|
try {
|
|
693
697
|
const { loadConfigSafe: loadConfigSafe2, migrateDataDirOnce: migrateDataDirOnce2 } = (init_config_loader(), __toCommonJS(exports_config_loader));
|
|
694
698
|
migrateDataDirOnce2();
|
|
@@ -12168,11 +12172,7 @@ class Logger {
|
|
|
12168
12172
|
return `[${timestamp}] [${level}] ${message}${metaStr}`;
|
|
12169
12173
|
}
|
|
12170
12174
|
write(message, level) {
|
|
12171
|
-
|
|
12172
|
-
console.error(message);
|
|
12173
|
-
} else {
|
|
12174
|
-
console.log(message);
|
|
12175
|
-
}
|
|
12175
|
+
console.error(message);
|
|
12176
12176
|
}
|
|
12177
12177
|
debug(message, meta) {
|
|
12178
12178
|
if (this.shouldLog(LogLevel.DEBUG)) {
|
|
@@ -12616,8 +12616,9 @@ class FileFilterCache {
|
|
|
12616
12616
|
}
|
|
12617
12617
|
invalidateProject(projectId) {
|
|
12618
12618
|
let removed = 0;
|
|
12619
|
+
const prefix = `project:${projectId}`;
|
|
12619
12620
|
for (const [key, _entry] of this.cache.entries()) {
|
|
12620
|
-
if (key.startsWith(
|
|
12621
|
+
if (key === prefix || key.startsWith(`${prefix}|`)) {
|
|
12621
12622
|
this.cache.delete(key);
|
|
12622
12623
|
removed++;
|
|
12623
12624
|
}
|
|
@@ -108648,9 +108649,9 @@ class SearchCachePg {
|
|
|
108648
108649
|
if (this.l1Cache.size <= this.L1_MAX_SIZE)
|
|
108649
108650
|
return;
|
|
108650
108651
|
let oldestKey = null;
|
|
108651
|
-
let oldestTime =
|
|
108652
|
+
let oldestTime = Infinity;
|
|
108652
108653
|
for (const [key, entry2] of this.l1Cache.entries()) {
|
|
108653
|
-
if (entry2.lastAccessed
|
|
108654
|
+
if (entry2.lastAccessed <= oldestTime) {
|
|
108654
108655
|
oldestTime = entry2.lastAccessed;
|
|
108655
108656
|
oldestKey = key;
|
|
108656
108657
|
}
|
|
@@ -109259,7 +109260,8 @@ function generationDefinitionIdentityColumns(def) {
|
|
|
109259
109260
|
}
|
|
109260
109261
|
if (parsed.kind !== def.kind)
|
|
109261
109262
|
throw new TypeError(`definition_fqn_kind_mismatch:${def.id}`);
|
|
109262
|
-
|
|
109263
|
+
const terminalMatchesName = parsed.qualifiedName === def.name || parsed.qualifiedName.endsWith(`.${def.name}`);
|
|
109264
|
+
if (!terminalMatchesName) {
|
|
109263
109265
|
throw new TypeError(`definition_fqn_name_mismatch:${def.id}`);
|
|
109264
109266
|
}
|
|
109265
109267
|
if (def.qualified_name !== undefined && def.qualified_name !== parsed.qualifiedName) {
|
|
@@ -109546,11 +109548,24 @@ async function writeFileGeneration(input) {
|
|
|
109546
109548
|
last_known_good_generation_id = EXCLUDED.last_known_good_generation_id,
|
|
109547
109549
|
last_successful_at = EXCLUDED.last_successful_at
|
|
109548
109550
|
`;
|
|
109549
|
-
|
|
109551
|
+
const seenDefinitionIds = new Set;
|
|
109552
|
+
const uniqueDefinitions = definitions.filter((definition) => {
|
|
109553
|
+
if (seenDefinitionIds.has(definition.id))
|
|
109554
|
+
return false;
|
|
109555
|
+
seenDefinitionIds.add(definition.id);
|
|
109556
|
+
return true;
|
|
109557
|
+
});
|
|
109558
|
+
for (const definition of uniqueDefinitions) {
|
|
109550
109559
|
const identity = generationDefinitionIdentityColumns(definition);
|
|
109551
109560
|
await tx.$executeRaw`
|
|
109552
109561
|
INSERT INTO symbol_definitions (id, project_id, generation_id, file_path, name, kind, line_start, line_end, exported, doc_comment, indexed_at, qualified_name, canonical_signature, signature_hash, legacy_fqn, source_span)
|
|
109553
109562
|
VALUES (${definition.id}, ${lease.projectId}, ${lease.generationId}, ${file3.relative_path}, ${definition.name}, ${definition.kind}, ${definition.line_start}, ${definition.line_end}, ${definition.exported}, ${definition.doc_comment ?? null}, ${new Date(definition.indexed_at)}, ${identity.qualifiedName}, ${identity.canonicalSignature}, ${identity.signatureHash}, ${identity.legacyFqn}, ${identity.sourceSpan}::jsonb)
|
|
109563
|
+
ON CONFLICT (project_id, generation_id, id) DO UPDATE SET
|
|
109564
|
+
name = EXCLUDED.name, kind = EXCLUDED.kind, line_start = EXCLUDED.line_start,
|
|
109565
|
+
line_end = EXCLUDED.line_end, exported = EXCLUDED.exported, doc_comment = EXCLUDED.doc_comment,
|
|
109566
|
+
indexed_at = EXCLUDED.indexed_at, qualified_name = EXCLUDED.qualified_name,
|
|
109567
|
+
canonical_signature = EXCLUDED.canonical_signature, signature_hash = EXCLUDED.signature_hash,
|
|
109568
|
+
legacy_fqn = EXCLUDED.legacy_fqn, source_span = EXCLUDED.source_span
|
|
109554
109569
|
`;
|
|
109555
109570
|
}
|
|
109556
109571
|
for (const reference of references) {
|
|
@@ -109801,7 +109816,7 @@ async function upsertWorkspace(ws) {
|
|
|
109801
109816
|
AND generation.id = 'legacy-' || md5(current_workspace.project_id)
|
|
109802
109817
|
AND generation.project_id = current_workspace.project_id
|
|
109803
109818
|
`;
|
|
109804
|
-
});
|
|
109819
|
+
}, { timeout: 60000, maxWait: 1e4 });
|
|
109805
109820
|
}
|
|
109806
109821
|
async function updateWorkspaceStatus(projectId, status2, opts) {
|
|
109807
109822
|
const lastError = typeof opts === "string" ? opts : opts?.lastError ?? null;
|
|
@@ -109872,7 +109887,7 @@ async function updateWorkspaceStatus(projectId, status2, opts) {
|
|
|
109872
109887
|
FROM active_counts c
|
|
109873
109888
|
WHERE w.project_id = c.project_id AND EXISTS (SELECT 1 FROM updated_generation)
|
|
109874
109889
|
`;
|
|
109875
|
-
});
|
|
109890
|
+
}, { timeout: 60000, maxWait: 1e4 });
|
|
109876
109891
|
}
|
|
109877
109892
|
var init_symbol_repo_workspace = __esm(() => {
|
|
109878
109893
|
init_prisma_client();
|
|
@@ -111481,7 +111496,7 @@ class MemoryRepositoryPg {
|
|
|
111481
111496
|
importance: m2.importance,
|
|
111482
111497
|
tags: JSON.stringify(tagsArr),
|
|
111483
111498
|
embedding: m2.embedding,
|
|
111484
|
-
metadata: m2.metadata ? JSON.stringify(m2.metadata)
|
|
111499
|
+
metadata: m2.metadata == null ? null : typeof m2.metadata === "string" ? m2.metadata : JSON.stringify(m2.metadata),
|
|
111485
111500
|
created_at: m2.created_at instanceof Date ? m2.created_at.getTime() : Number(m2.created_at),
|
|
111486
111501
|
updated_at: m2.updated_at instanceof Date ? m2.updated_at.getTime() : Number(m2.updated_at),
|
|
111487
111502
|
access_count: m2.access_count,
|
|
@@ -111675,7 +111690,7 @@ class MemoryRepositoryPg {
|
|
|
111675
111690
|
pinned, deleted_at
|
|
111676
111691
|
FROM memories
|
|
111677
111692
|
WHERE deleted_at IS NULL
|
|
111678
|
-
ORDER BY created_at DESC
|
|
111693
|
+
ORDER BY created_at DESC, id DESC
|
|
111679
111694
|
LIMIT ${limit} OFFSET ${offset}
|
|
111680
111695
|
`;
|
|
111681
111696
|
return rows.map((r2) => this.toMemoryRow(r2));
|
|
@@ -111683,7 +111698,7 @@ class MemoryRepositoryPg {
|
|
|
111683
111698
|
async findRecentByTag(tag, opts) {
|
|
111684
111699
|
const since = new Date(opts.sinceMs);
|
|
111685
111700
|
const conditions = [
|
|
111686
|
-
import_prisma2.Prisma.sql`${tag} = ANY(tags)`,
|
|
111701
|
+
import_prisma2.Prisma.sql`${tag} = ANY(tags::text[])`,
|
|
111687
111702
|
import_prisma2.Prisma.sql`created_at >= ${since}`
|
|
111688
111703
|
];
|
|
111689
111704
|
if (opts.sessionId)
|
|
@@ -112226,7 +112241,8 @@ function restoreWorkingMemoryBuffer(snapshot) {
|
|
|
112226
112241
|
for (const e of snapshot.entries) {
|
|
112227
112242
|
if (!e || !e.result || typeof e.id !== "string")
|
|
112228
112243
|
continue;
|
|
112229
|
-
|
|
112244
|
+
const lastAccessedAt = e.lastAccessedAt ?? now2;
|
|
112245
|
+
if (now2 - lastAccessedAt >= snapshot.config.ttlMs)
|
|
112230
112246
|
continue;
|
|
112231
112247
|
const result = e.result;
|
|
112232
112248
|
buf.entries.set(e.id, {
|
|
@@ -112234,7 +112250,7 @@ function restoreWorkingMemoryBuffer(snapshot) {
|
|
|
112234
112250
|
queryTokens: new Set,
|
|
112235
112251
|
contentTokens: tokenize(result.content || ""),
|
|
112236
112252
|
addedAt: e.addedAt ?? now2,
|
|
112237
|
-
lastAccessedAt
|
|
112253
|
+
lastAccessedAt,
|
|
112238
112254
|
baselineScore: e.baselineScore ?? result.score
|
|
112239
112255
|
});
|
|
112240
112256
|
}
|
|
@@ -118797,6 +118813,7 @@ function buildStructuralResolverDefinitions(documents) {
|
|
|
118797
118813
|
return Object.freeze(documents.flatMap((document2) => document2.structure.symbols.map((symbol27) => {
|
|
118798
118814
|
const key = `${document2.file}\x00${symbol27.qualifiedName}\x00${symbol27.kind}`;
|
|
118799
118815
|
const visibleNested = document2.dialect === "java" ? symbol27.signatureMaterial.modifiers.includes("public") && (["class", "interface", "enum"].includes(symbol27.kind) || symbol27.signatureMaterial.modifiers.includes("static")) : !symbol27.signatureMaterial.modifiers.includes("private");
|
|
118816
|
+
const isExportMarker = symbol27.kind === "export";
|
|
118800
118817
|
return Object.freeze({
|
|
118801
118818
|
identity: Object.freeze({
|
|
118802
118819
|
file: document2.file,
|
|
@@ -118809,7 +118826,7 @@ function buildStructuralResolverDefinitions(documents) {
|
|
|
118809
118826
|
typeTokens: symbol27.signatureMaterial.typeTokens,
|
|
118810
118827
|
modifiers: symbol27.signatureMaterial.modifiers,
|
|
118811
118828
|
scope: symbol27.qualifiedName === symbol27.name ? "top_level" : "nested",
|
|
118812
|
-
overload: (groups.get(key) ?? 0) > 1 ? "overloaded" : "unique"
|
|
118829
|
+
overload: (groups.get(key) ?? 0) > 1 || isExportMarker ? "overloaded" : "unique"
|
|
118813
118830
|
}),
|
|
118814
118831
|
exported: symbol27.exported || !symbol27.name.startsWith("#") && !symbol27.name.startsWith("%23") && visibleNested && exportedRoots.has(`${document2.file}\x00${symbol27.qualifiedName.split(".")[0]}`),
|
|
118815
118832
|
defaultExport: symbol27.defaultExport
|
|
@@ -119478,6 +119495,7 @@ class ResolveStage {
|
|
|
119478
119495
|
timestamp: Date.now()
|
|
119479
119496
|
});
|
|
119480
119497
|
}
|
|
119498
|
+
await new Promise((resolve5) => setTimeout(resolve5, 0));
|
|
119481
119499
|
}
|
|
119482
119500
|
const durationMs = Math.round(performance.now() - t0);
|
|
119483
119501
|
ctx.emit({
|
|
@@ -119801,6 +119819,47 @@ var init_resolve = __esm(() => {
|
|
|
119801
119819
|
STRUCTURAL_SEED_EXTENSIONS = new Set([".ts", ".tsx", ".js", ".jsx", ".py", ".rb", ".php", ".lua", ".c", ".h", ".cpp", ".hpp", ".go", ".rs", ".zig", ".java", ".kt", ".kts", ".scala", ".cs", ".swift", ".dart", ".ex", ".exs", ".erl", ".clj", ".ml", ".hs", ".vue", ".md", ".json", ".yaml", ".yml"]);
|
|
119802
119820
|
});
|
|
119803
119821
|
|
|
119822
|
+
// ../../packages/core/dist/data/with-deadlock-retry.js
|
|
119823
|
+
function isRetriableTransactionError(error51) {
|
|
119824
|
+
if (!error51 || typeof error51 !== "object")
|
|
119825
|
+
return false;
|
|
119826
|
+
const code = error51.code;
|
|
119827
|
+
if (typeof code === "string" && RETRIABLE_SQLSTATES.has(code))
|
|
119828
|
+
return true;
|
|
119829
|
+
const message = error51.message;
|
|
119830
|
+
if (typeof message === "string" && /Code:\s*`(?:40P01|40001|40P02)`/.test(message)) {
|
|
119831
|
+
return true;
|
|
119832
|
+
}
|
|
119833
|
+
return false;
|
|
119834
|
+
}
|
|
119835
|
+
async function withDeadlockRetry(operation, options = {}) {
|
|
119836
|
+
const maxAttempts = options.maxAttempts ?? 5;
|
|
119837
|
+
const baseDelayMs = options.baseDelayMs ?? 75;
|
|
119838
|
+
for (let attempt = 1;attempt <= maxAttempts; attempt++) {
|
|
119839
|
+
try {
|
|
119840
|
+
return await operation();
|
|
119841
|
+
} catch (error51) {
|
|
119842
|
+
if (!isRetriableTransactionError(error51) || attempt === maxAttempts)
|
|
119843
|
+
throw error51;
|
|
119844
|
+
const delayMs = baseDelayMs * 2 ** (attempt - 1);
|
|
119845
|
+
logger.warn("Retriable DB lock cycle; retrying operation", {
|
|
119846
|
+
operation: options.operation ?? "unknown",
|
|
119847
|
+
attempt,
|
|
119848
|
+
maxAttempts,
|
|
119849
|
+
delayMs,
|
|
119850
|
+
error: error51?.message?.slice(0, 120)
|
|
119851
|
+
});
|
|
119852
|
+
await new Promise((resolve5) => setTimeout(resolve5, delayMs));
|
|
119853
|
+
}
|
|
119854
|
+
}
|
|
119855
|
+
throw new Error("withDeadlockRetry exhausted retries");
|
|
119856
|
+
}
|
|
119857
|
+
var RETRIABLE_SQLSTATES;
|
|
119858
|
+
var init_with_deadlock_retry = __esm(() => {
|
|
119859
|
+
init_dist();
|
|
119860
|
+
RETRIABLE_SQLSTATES = new Set(["40P01", "40001", "40P02"]);
|
|
119861
|
+
});
|
|
119862
|
+
|
|
119804
119863
|
// ../../packages/core/dist/services/etl/stages/load.js
|
|
119805
119864
|
import path15 from "path";
|
|
119806
119865
|
function formatDuration(ms) {
|
|
@@ -119917,8 +119976,12 @@ class LoadStage {
|
|
|
119917
119976
|
return;
|
|
119918
119977
|
try {
|
|
119919
119978
|
const [chunkCount, symCount] = await Promise.all([
|
|
119920
|
-
mode === "structural" ? Promise.resolve(0) : this.loadToSearchStores(ctx, file3),
|
|
119921
|
-
|
|
119979
|
+
mode === "structural" ? Promise.resolve(0) : withDeadlockRetry(() => this.loadToSearchStores(ctx, file3), {
|
|
119980
|
+
operation: "etl.loadToSearchStores"
|
|
119981
|
+
}),
|
|
119982
|
+
mode === "semantic" ? Promise.resolve(file3.symbols.length) : withDeadlockRetry(() => this.loadToSymbolDb(ctx, file3), {
|
|
119983
|
+
operation: "etl.loadToSymbolDb"
|
|
119984
|
+
})
|
|
119922
119985
|
]);
|
|
119923
119986
|
if (!ctx.graphGenerationLease && mode !== "structural") {
|
|
119924
119987
|
await getSymbolRepository().upsertFile({
|
|
@@ -120110,6 +120173,7 @@ class LoadStage {
|
|
|
120110
120173
|
}
|
|
120111
120174
|
var init_load = __esm(() => {
|
|
120112
120175
|
init_dist();
|
|
120176
|
+
init_with_deadlock_retry();
|
|
120113
120177
|
init_vector_store_factory();
|
|
120114
120178
|
init_keyword_search_factory();
|
|
120115
120179
|
init_symbol_repository_factory();
|
|
@@ -120307,7 +120371,7 @@ class GraphGenerationRepositoryPg {
|
|
|
120307
120371
|
AND graph_lease_token = ${lease.leaseToken}
|
|
120308
120372
|
`;
|
|
120309
120373
|
return { status: "renewed", leaseExpiresAt: renewed[0].lease_expires_at.getTime() };
|
|
120310
|
-
});
|
|
120374
|
+
}, { timeout: 60000, maxWait: 1e4 });
|
|
120311
120375
|
}
|
|
120312
120376
|
async complete(lease) {
|
|
120313
120377
|
return getPrismaClient2().$transaction(async (tx) => {
|
|
@@ -120481,7 +120545,7 @@ class GraphGenerationCoordinator {
|
|
|
120481
120545
|
} while (true);
|
|
120482
120546
|
}
|
|
120483
120547
|
async heartbeat(lease) {
|
|
120484
|
-
const outcome2 = await this.repository.heartbeat(lease, GRAPH_GENERATION_LEASE_TTL_MS);
|
|
120548
|
+
const outcome2 = await withDeadlockRetry(() => this.repository.heartbeat(lease, GRAPH_GENERATION_LEASE_TTL_MS), { operation: "graph_generation.heartbeat", maxAttempts: 3 });
|
|
120485
120549
|
if (outcome2.status !== "renewed")
|
|
120486
120550
|
throw new Error("graph_generation_lease_lost");
|
|
120487
120551
|
}
|
|
@@ -120517,6 +120581,7 @@ class GraphGenerationCoordinator {
|
|
|
120517
120581
|
var GRAPH_GENERATION_LEASE_TTL_MS = 300000;
|
|
120518
120582
|
var init_graph_generation_coordinator = __esm(() => {
|
|
120519
120583
|
init_graph_generation_repository_factory();
|
|
120584
|
+
init_with_deadlock_retry();
|
|
120520
120585
|
});
|
|
120521
120586
|
|
|
120522
120587
|
// ../../packages/core/dist/services/etl/pipeline.js
|
|
@@ -120594,6 +120659,7 @@ var init_pipeline = __esm(() => {
|
|
|
120594
120659
|
init_symbol_repository_factory();
|
|
120595
120660
|
init_index_job_tracker();
|
|
120596
120661
|
init_cache_factory();
|
|
120662
|
+
init_index_manager();
|
|
120597
120663
|
init_vector_store_factory();
|
|
120598
120664
|
init_keyword_search_factory();
|
|
120599
120665
|
init_alias_resolver();
|
|
@@ -120885,6 +120951,16 @@ var init_pipeline = __esm(() => {
|
|
|
120885
120951
|
}
|
|
120886
120952
|
};
|
|
120887
120953
|
await getSearchCache().invalidateProject(projectId);
|
|
120954
|
+
try {
|
|
120955
|
+
const admissionMarker = new IndexManager(await getVectorStore());
|
|
120956
|
+
await admissionMarker.updateIndexMetadata(projectId, projectPath, discovered.map((file3) => file3.relativePath));
|
|
120957
|
+
} catch (markerError) {
|
|
120958
|
+
logger.warn("EtlPipeline: search-admission marker write failed", {
|
|
120959
|
+
projectId,
|
|
120960
|
+
jobId,
|
|
120961
|
+
error: markerError.message.slice(0, 160)
|
|
120962
|
+
});
|
|
120963
|
+
}
|
|
120888
120964
|
indexJobTracker.updateProgress(jobId, result.filesIndexed, result.filesIndexed);
|
|
120889
120965
|
await indexJobTracker.setResultAndFlush(jobId, {
|
|
120890
120966
|
filesIndexed: result.filesIndexed,
|
|
@@ -123045,10 +123121,10 @@ class GraphQueries {
|
|
|
123045
123121
|
return new Map;
|
|
123046
123122
|
}
|
|
123047
123123
|
const rows = await getPrismaClient2().$queryRaw`
|
|
123048
|
-
SELECT id, content, type, level, importance,
|
|
123124
|
+
SELECT id, content, type, level, importance, tags,
|
|
123049
123125
|
created_at, updated_at, access_count, user_id, session_id, project_id, agent_id,
|
|
123050
123126
|
NULL::bytea AS embedding, NULL::text AS metadata, NULL::timestamp AS last_accessed,
|
|
123051
|
-
pinned
|
|
123127
|
+
CASE WHEN pinned THEN 1 ELSE 0 END AS pinned, deleted_at
|
|
123052
123128
|
FROM memories WHERE id = ANY(${memoryIds}::text[])`;
|
|
123053
123129
|
const result = new Map;
|
|
123054
123130
|
for (const row of rows) {
|
|
@@ -125229,16 +125305,14 @@ var TOOL_NAME_NORMALIZE, classifyToolCall = (_source, payload) => {
|
|
|
125229
125305
|
const cmdRaw = field2(payload, "command") ?? (toolInput && typeof toolInput === "object" ? toolInput.command : undefined);
|
|
125230
125306
|
const cmd = lower(cmdRaw);
|
|
125231
125307
|
if (cmd.startsWith("git ") || cmd.includes(" git ")) {
|
|
125232
|
-
if (cmd.includes("commit") || cmd.includes("merge") || cmd.includes("rebase")) {
|
|
125233
|
-
return "git-changes";
|
|
125234
|
-
}
|
|
125235
125308
|
return "git-changes";
|
|
125236
125309
|
}
|
|
125237
125310
|
return "tool-calls";
|
|
125238
125311
|
}
|
|
125239
125312
|
case "TodoWrite":
|
|
125240
|
-
case "Task":
|
|
125241
125313
|
return "tasks";
|
|
125314
|
+
case "Task":
|
|
125315
|
+
return "subagents-spawned";
|
|
125242
125316
|
case "WebFetch":
|
|
125243
125317
|
return "web-fetch";
|
|
125244
125318
|
case "WebSearch":
|
|
@@ -125255,8 +125329,6 @@ var TOOL_NAME_NORMALIZE, classifyToolCall = (_source, payload) => {
|
|
|
125255
125329
|
return "memories-stored";
|
|
125256
125330
|
case "compact_snapshot":
|
|
125257
125331
|
return "compaction-snapshots";
|
|
125258
|
-
case "Task":
|
|
125259
|
-
return "subagents-spawned";
|
|
125260
125332
|
default:
|
|
125261
125333
|
if (toolName.startsWith("mcp__"))
|
|
125262
125334
|
return "mcp-calls";
|
|
@@ -172930,7 +173002,7 @@ class CompressContextTool {
|
|
|
172930
173002
|
} catch (error51) {
|
|
172931
173003
|
logger.error("Failed to compress context", error51, {
|
|
172932
173004
|
strategy,
|
|
172933
|
-
contentLength: content.length
|
|
173005
|
+
contentLength: typeof content === "string" ? content.length : 0
|
|
172934
173006
|
});
|
|
172935
173007
|
return {
|
|
172936
173008
|
success: false,
|
|
@@ -177893,9 +177965,11 @@ var systemRoutes = new Elysia({ prefix: "/api/v1/system" }).get("/info", async (
|
|
|
177893
177965
|
});
|
|
177894
177966
|
|
|
177895
177967
|
// src/routes/events.ts
|
|
177896
|
-
var
|
|
177897
|
-
var
|
|
177968
|
+
var HEARTBEAT_MS_DEFAULT = 15000;
|
|
177969
|
+
var MAX_DURATION_MS_DEFAULT = 10 * 60 * 1000;
|
|
177898
177970
|
var eventsRoutes = new Elysia({ prefix: "/api/v1" }).get("/events", async ({ query, set: set3 }) => {
|
|
177971
|
+
const HEARTBEAT_MS = Number(process.env.MASSA_AI_SSE_HEARTBEAT_MS) || HEARTBEAT_MS_DEFAULT;
|
|
177972
|
+
const MAX_DURATION_MS = Number(process.env.MASSA_AI_SSE_MAX_DURATION_MS) || MAX_DURATION_MS_DEFAULT;
|
|
177899
177973
|
const projectIdFilter = query.projectId;
|
|
177900
177974
|
const jobIdFilter = query.jobId;
|
|
177901
177975
|
set3.headers["Content-Type"] = "text/event-stream";
|
|
@@ -177904,6 +177978,9 @@ var eventsRoutes = new Elysia({ prefix: "/api/v1" }).get("/events", async ({ que
|
|
|
177904
177978
|
set3.headers["X-Accel-Buffering"] = "no";
|
|
177905
177979
|
const encoder3 = new TextEncoder;
|
|
177906
177980
|
let closed = false;
|
|
177981
|
+
let unsubscribers = [];
|
|
177982
|
+
let heartbeatTimer;
|
|
177983
|
+
let closeTimer;
|
|
177907
177984
|
const stream2 = new ReadableStream({
|
|
177908
177985
|
start(controller) {
|
|
177909
177986
|
const enqueue = (data) => {
|
|
@@ -177925,14 +178002,14 @@ var eventsRoutes = new Elysia({ prefix: "/api/v1" }).get("/events", async ({ que
|
|
|
177925
178002
|
"indexing:failed",
|
|
177926
178003
|
"workspace:updated"
|
|
177927
178004
|
];
|
|
177928
|
-
|
|
178005
|
+
unsubscribers = events.map((event) => eventBus.subscribe(event, (payload) => {
|
|
177929
178006
|
if (projectIdFilter && payload.projectId !== projectIdFilter)
|
|
177930
178007
|
return;
|
|
177931
178008
|
if (jobIdFilter && payload.jobId !== jobIdFilter)
|
|
177932
178009
|
return;
|
|
177933
178010
|
enqueue({ event, payload, timestamp: new Date().toISOString() });
|
|
177934
178011
|
}));
|
|
177935
|
-
|
|
178012
|
+
heartbeatTimer = setInterval(() => {
|
|
177936
178013
|
if (closed) {
|
|
177937
178014
|
clearInterval(heartbeatTimer);
|
|
177938
178015
|
return;
|
|
@@ -177946,7 +178023,7 @@ var eventsRoutes = new Elysia({ prefix: "/api/v1" }).get("/events", async ({ que
|
|
|
177946
178023
|
clearInterval(heartbeatTimer);
|
|
177947
178024
|
}
|
|
177948
178025
|
}, HEARTBEAT_MS);
|
|
177949
|
-
|
|
178026
|
+
closeTimer = setTimeout(() => {
|
|
177950
178027
|
closed = true;
|
|
177951
178028
|
unsubscribers.forEach((u) => u());
|
|
177952
178029
|
clearInterval(heartbeatTimer);
|
|
@@ -177962,12 +178039,14 @@ var eventsRoutes = new Elysia({ prefix: "/api/v1" }).get("/events", async ({ que
|
|
|
177962
178039
|
},
|
|
177963
178040
|
timestamp: new Date().toISOString()
|
|
177964
178041
|
});
|
|
177965
|
-
|
|
177966
|
-
|
|
177967
|
-
|
|
178042
|
+
},
|
|
178043
|
+
cancel() {
|
|
178044
|
+
closed = true;
|
|
178045
|
+
unsubscribers.forEach((u) => u());
|
|
178046
|
+
if (heartbeatTimer)
|
|
177968
178047
|
clearInterval(heartbeatTimer);
|
|
178048
|
+
if (closeTimer)
|
|
177969
178049
|
clearTimeout(closeTimer);
|
|
177970
|
-
};
|
|
177971
178050
|
}
|
|
177972
178051
|
});
|
|
177973
178052
|
return new Response(stream2, {
|
|
@@ -179442,21 +179521,22 @@ var webRoutes = new Elysia({ prefix: "/api/v1/web" }).post("/fetch_and_index", a
|
|
|
179442
179521
|
import fs17 from "fs/promises";
|
|
179443
179522
|
import path27 from "path";
|
|
179444
179523
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
179445
|
-
|
|
179446
|
-
const here = path27.dirname(fileURLToPath3(import.meta.url));
|
|
179524
|
+
function buildStaticDirCandidates(moduleDir, cwd) {
|
|
179447
179525
|
const candidates2 = [];
|
|
179448
|
-
|
|
179449
|
-
|
|
179450
|
-
|
|
179451
|
-
|
|
179452
|
-
|
|
179453
|
-
|
|
179454
|
-
|
|
179455
|
-
|
|
179456
|
-
|
|
179526
|
+
for (const root2 of [moduleDir, cwd]) {
|
|
179527
|
+
let dir = root2;
|
|
179528
|
+
for (let i = 0;i < 10; i++) {
|
|
179529
|
+
candidates2.push(path27.resolve(dir, "apps/web-ui/src/static"));
|
|
179530
|
+
candidates2.push(path27.resolve(dir, "web-ui/src/static"));
|
|
179531
|
+
const parent = path27.dirname(dir);
|
|
179532
|
+
if (parent === dir)
|
|
179533
|
+
break;
|
|
179534
|
+
dir = parent;
|
|
179535
|
+
}
|
|
179457
179536
|
}
|
|
179458
|
-
return candidates2;
|
|
179459
|
-
}
|
|
179537
|
+
return [...new Set(candidates2)];
|
|
179538
|
+
}
|
|
179539
|
+
var STATIC_DIR_CANDIDATES = buildStaticDirCandidates(path27.dirname(fileURLToPath3(import.meta.url)), process.cwd());
|
|
179460
179540
|
async function resolveStaticDir() {
|
|
179461
179541
|
for (const dir of STATIC_DIR_CANDIDATES) {
|
|
179462
179542
|
try {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@massa-ai/tools-api",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.1",
|
|
4
4
|
"author": "luizgmassa",
|
|
5
5
|
"description": "massa-ai REST API server - Semantic code search, memory, and context compression",
|
|
6
6
|
"type": "module",
|
|
@@ -21,8 +21,8 @@
|
|
|
21
21
|
"test": "bun scripts/run-tests-isolated.ts"
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@massa-ai/core": "^1.
|
|
25
|
-
"@massa-ai/shared": "^1.
|
|
24
|
+
"@massa-ai/core": "^1.3.1",
|
|
25
|
+
"@massa-ai/shared": "^1.3.1",
|
|
26
26
|
"elysia": "^1.2.25",
|
|
27
27
|
"@elysiajs/swagger": "^1.2.0",
|
|
28
28
|
"@elysiajs/cors": "^1.2.0",
|