@axiom-lattice/gateway 3.0.7 → 3.0.9
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 -9
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +136 -9
- package/dist/index.mjs.map +1 -1
- package/package.json +6 -6
package/dist/index.js
CHANGED
|
@@ -2722,6 +2722,125 @@ var getAgentGraph = async (request, reply) => {
|
|
|
2722
2722
|
});
|
|
2723
2723
|
}
|
|
2724
2724
|
};
|
|
2725
|
+
var STATS_CACHE_TTL_MS = 5 * 60 * 1e3;
|
|
2726
|
+
var statsCache = /* @__PURE__ */ new Map();
|
|
2727
|
+
async function getAssistantStats(request, reply) {
|
|
2728
|
+
const tenantId = getTenantId(request);
|
|
2729
|
+
const cached = statsCache.get(tenantId);
|
|
2730
|
+
if (cached && cached.expiresAt > Date.now()) {
|
|
2731
|
+
return {
|
|
2732
|
+
success: true,
|
|
2733
|
+
message: "Ok (cached)",
|
|
2734
|
+
data: cached.data,
|
|
2735
|
+
cache: {
|
|
2736
|
+
expiresAt: new Date(cached.expiresAt).toISOString(),
|
|
2737
|
+
remainingMs: cached.expiresAt - Date.now(),
|
|
2738
|
+
cached: true
|
|
2739
|
+
}
|
|
2740
|
+
};
|
|
2741
|
+
}
|
|
2742
|
+
try {
|
|
2743
|
+
const agentConfigs = await import_core2.agentLatticeManager.getAllAgentConfigsByTenant(tenantId);
|
|
2744
|
+
const codeConfiguredAssistants = agentConfigs.map(convertAgentConfigToAssistant);
|
|
2745
|
+
const storeLattice = (0, import_core.getStoreLattice)("default", "assistant");
|
|
2746
|
+
const assistantStore = storeLattice.store;
|
|
2747
|
+
const storedAssistants = await assistantStore.getAllAssistants(tenantId);
|
|
2748
|
+
const assistantMap = /* @__PURE__ */ new Map();
|
|
2749
|
+
codeConfiguredAssistants.forEach((a) => assistantMap.set(a.id, a));
|
|
2750
|
+
storedAssistants.forEach((a) => assistantMap.set(a.id, a));
|
|
2751
|
+
const userId = getUserId(request);
|
|
2752
|
+
const assistants = Array.from(assistantMap.values()).filter((a) => {
|
|
2753
|
+
if (!a.ownerUserId) return true;
|
|
2754
|
+
return a.ownerUserId === userId;
|
|
2755
|
+
});
|
|
2756
|
+
const threadStore = (0, import_core.getStoreLattice)("default", "thread").store;
|
|
2757
|
+
const evalStore = (0, import_core.getStoreLattice)("default", "eval").store;
|
|
2758
|
+
const now = Date.now();
|
|
2759
|
+
const ms7d = 7 * 864e5;
|
|
2760
|
+
const ms30d = 30 * 864e5;
|
|
2761
|
+
const records = await Promise.all(
|
|
2762
|
+
assistants.map(async (assistant) => {
|
|
2763
|
+
let threadCount = 0;
|
|
2764
|
+
let last7d = 0;
|
|
2765
|
+
let last30d = 0;
|
|
2766
|
+
let lastActive = null;
|
|
2767
|
+
const daily7d = new Array(7).fill(0);
|
|
2768
|
+
const daily30d = new Array(30).fill(0);
|
|
2769
|
+
try {
|
|
2770
|
+
const threads = await threadStore.getThreadsByAssistantId(tenantId, assistant.id);
|
|
2771
|
+
threadCount = threads.length;
|
|
2772
|
+
for (const t of threads) {
|
|
2773
|
+
const created = new Date(t.createdAt).getTime();
|
|
2774
|
+
if (created >= now - ms7d) last7d++;
|
|
2775
|
+
if (created >= now - ms30d) last30d++;
|
|
2776
|
+
const idx7 = Math.floor((now - created) / 864e5);
|
|
2777
|
+
if (idx7 >= 0 && idx7 < 7) daily7d[6 - idx7]++;
|
|
2778
|
+
const idx30 = Math.floor((now - created) / 864e5);
|
|
2779
|
+
if (idx30 >= 0 && idx30 < 30) daily30d[29 - idx30]++;
|
|
2780
|
+
const updated = new Date(t.updatedAt).getTime();
|
|
2781
|
+
if (lastActive === null || updated > lastActive.getTime()) {
|
|
2782
|
+
lastActive = new Date(t.updatedAt);
|
|
2783
|
+
}
|
|
2784
|
+
}
|
|
2785
|
+
} catch {
|
|
2786
|
+
}
|
|
2787
|
+
let evalScore = null;
|
|
2788
|
+
let evalPassRate = null;
|
|
2789
|
+
let evalRuns = 0;
|
|
2790
|
+
let evalTrend = [];
|
|
2791
|
+
try {
|
|
2792
|
+
const projects = await evalStore.getProjectsByTenant(tenantId);
|
|
2793
|
+
const project = projects.find((p) => p.name === `eval-${assistant.id}`);
|
|
2794
|
+
if (project) {
|
|
2795
|
+
const runs = await evalStore.getRunsByTenant(tenantId, { projectId: project.id });
|
|
2796
|
+
evalRuns = runs.length;
|
|
2797
|
+
const sorted = [...runs].sort(
|
|
2798
|
+
(a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime()
|
|
2799
|
+
);
|
|
2800
|
+
evalTrend = sorted.map((r) => typeof r.avgScore === "number" ? r.avgScore : null).filter((v) => v !== null);
|
|
2801
|
+
const latest = sorted[sorted.length - 1];
|
|
2802
|
+
if (latest) {
|
|
2803
|
+
evalScore = typeof latest.avgScore === "number" ? latest.avgScore : null;
|
|
2804
|
+
if (latest.totalCases > 0) {
|
|
2805
|
+
evalPassRate = Math.round(latest.passedCases / latest.totalCases * 100);
|
|
2806
|
+
}
|
|
2807
|
+
}
|
|
2808
|
+
}
|
|
2809
|
+
} catch {
|
|
2810
|
+
}
|
|
2811
|
+
return {
|
|
2812
|
+
id: assistant.id,
|
|
2813
|
+
threadCount,
|
|
2814
|
+
last7d,
|
|
2815
|
+
last30d,
|
|
2816
|
+
lastActive: lastActive ? lastActive.toISOString() : null,
|
|
2817
|
+
daily7d,
|
|
2818
|
+
daily30d,
|
|
2819
|
+
evalScore,
|
|
2820
|
+
evalPassRate,
|
|
2821
|
+
evalRuns,
|
|
2822
|
+
evalTrend: evalTrend.slice(-8)
|
|
2823
|
+
};
|
|
2824
|
+
})
|
|
2825
|
+
);
|
|
2826
|
+
const payload = { records };
|
|
2827
|
+
const expiresAt = Date.now() + STATS_CACHE_TTL_MS;
|
|
2828
|
+
statsCache.set(tenantId, { data: payload, expiresAt });
|
|
2829
|
+
return {
|
|
2830
|
+
success: true,
|
|
2831
|
+
message: "Ok",
|
|
2832
|
+
data: payload,
|
|
2833
|
+
cache: {
|
|
2834
|
+
expiresAt: new Date(expiresAt).toISOString(),
|
|
2835
|
+
remainingMs: STATS_CACHE_TTL_MS,
|
|
2836
|
+
cached: false
|
|
2837
|
+
}
|
|
2838
|
+
};
|
|
2839
|
+
} catch (err) {
|
|
2840
|
+
const message = err instanceof Error ? err.message : "Failed to get assistant stats";
|
|
2841
|
+
return reply.status(500).send({ success: false, message });
|
|
2842
|
+
}
|
|
2843
|
+
}
|
|
2725
2844
|
|
|
2726
2845
|
// src/controllers/run.ts
|
|
2727
2846
|
var import_uuid = require("uuid");
|
|
@@ -5390,6 +5509,7 @@ async function listTasks(request, reply) {
|
|
|
5390
5509
|
priority: query.priority,
|
|
5391
5510
|
...query.ownerId && { ownerId: query.ownerId },
|
|
5392
5511
|
...query.ownerType && { ownerType: query.ownerType },
|
|
5512
|
+
...query.parentId && { parentId: query.parentId },
|
|
5393
5513
|
metadata: query.metadata ? JSON.parse(query.metadata) : void 0,
|
|
5394
5514
|
projectId: query.projectId,
|
|
5395
5515
|
limit: query.limit ? parseInt(query.limit) : void 0,
|
|
@@ -8222,7 +8342,7 @@ var EvalRunner = class {
|
|
|
8222
8342
|
getEventEmitter() {
|
|
8223
8343
|
return this.eventEmitter;
|
|
8224
8344
|
}
|
|
8225
|
-
async startRun(tenantId, projectId, suiteIds, caseIds, runConfig) {
|
|
8345
|
+
async startRun(tenantId, projectId, suiteIds, caseIds, runConfig, taskId) {
|
|
8226
8346
|
const store2 = this.getEvalStore();
|
|
8227
8347
|
const project = await store2.getProjectById(tenantId, projectId);
|
|
8228
8348
|
if (!project) throw new Error("Project not found");
|
|
@@ -8293,12 +8413,15 @@ var EvalRunner = class {
|
|
|
8293
8413
|
}
|
|
8294
8414
|
resolvedJudgeModelKey = judgeModelKey;
|
|
8295
8415
|
} else {
|
|
8296
|
-
const
|
|
8297
|
-
|
|
8416
|
+
const models = import_core31.modelLatticeManager.getAllLattices();
|
|
8417
|
+
const defaultModel = models.find((m) => m.key === "default");
|
|
8418
|
+
resolvedJudgeModelKey = defaultModel?.key ?? models[0]?.key ?? "";
|
|
8419
|
+
if (!resolvedJudgeModelKey) {
|
|
8298
8420
|
throw new Error("No model registered \u2014 cannot run eval without a judge model");
|
|
8299
8421
|
}
|
|
8300
|
-
|
|
8301
|
-
|
|
8422
|
+
if (!defaultModel) {
|
|
8423
|
+
console.warn(`[eval-runner] Project "${project.name}" has no judge modelKey and no "default" model \u2014 falling back to first registered model "${resolvedJudgeModelKey}"`);
|
|
8424
|
+
}
|
|
8302
8425
|
}
|
|
8303
8426
|
const runId = (0, import_uuid4.v4)();
|
|
8304
8427
|
const concurrency = Math.max(1, Math.floor(project.concurrency) || 3);
|
|
@@ -8310,7 +8433,8 @@ var EvalRunner = class {
|
|
|
8310
8433
|
concurrency,
|
|
8311
8434
|
holdout: isHoldout,
|
|
8312
8435
|
envWorkspaceId: workspaceId || void 0,
|
|
8313
|
-
envProjectId: projectIdFromConfig || void 0
|
|
8436
|
+
envProjectId: projectIdFromConfig || void 0,
|
|
8437
|
+
taskId
|
|
8314
8438
|
});
|
|
8315
8439
|
const projectConfig = {
|
|
8316
8440
|
projectName: project.name,
|
|
@@ -8417,7 +8541,7 @@ var EvalRunner = class {
|
|
|
8417
8541
|
this.runs.delete(runId);
|
|
8418
8542
|
}
|
|
8419
8543
|
})();
|
|
8420
|
-
this.runs.set(runId, { runId, projectId, tenantId, abortController, promise: runPromise });
|
|
8544
|
+
this.runs.set(runId, { runId, projectId, tenantId, abortController, promise: runPromise, taskId });
|
|
8421
8545
|
runPromise.catch(() => {
|
|
8422
8546
|
});
|
|
8423
8547
|
return runId;
|
|
@@ -8488,7 +8612,9 @@ async function createProject(request, reply) {
|
|
|
8488
8612
|
},
|
|
8489
8613
|
targetServerConfig: {
|
|
8490
8614
|
base_url: serverCfg.base_url || "",
|
|
8491
|
-
api_key: serverCfg.api_key || ""
|
|
8615
|
+
api_key: serverCfg.api_key || "",
|
|
8616
|
+
// Project↔agent association pointer (see manage_eval create_project).
|
|
8617
|
+
...serverCfg.targetAgentId ? { targetAgentId: serverCfg.targetAgentId } : {}
|
|
8492
8618
|
},
|
|
8493
8619
|
concurrency: data.concurrency ?? 1,
|
|
8494
8620
|
reportConfig: data.reportConfig
|
|
@@ -8797,7 +8923,7 @@ function registerEvalRoutes(app2) {
|
|
|
8797
8923
|
workspaceId: body?.runConfig?.workspaceId ?? bodyWs,
|
|
8798
8924
|
projectId: body?.runConfig?.projectId ?? bodyPj
|
|
8799
8925
|
};
|
|
8800
|
-
const runId = await evalRunner.startRun(tenantId, pid, body?.suiteIds, body?.caseIds, runConfig);
|
|
8926
|
+
const runId = await evalRunner.startRun(tenantId, pid, body?.suiteIds, body?.caseIds, runConfig, body?.taskId);
|
|
8801
8927
|
reply.status(202).send({ success: true, message: "Run started", data: { run_id: runId } });
|
|
8802
8928
|
} catch (err) {
|
|
8803
8929
|
const msg = err.message;
|
|
@@ -10801,6 +10927,7 @@ var registerLatticeRoutes = (app2, channelDeps) => {
|
|
|
10801
10927
|
clearMemory
|
|
10802
10928
|
);
|
|
10803
10929
|
app2.get("/api/assistants", getAssistantList);
|
|
10930
|
+
app2.get("/api/assistants/stats", getAssistantStats);
|
|
10804
10931
|
app2.get("/api/assistants/:id", getAssistant);
|
|
10805
10932
|
app2.post("/api/assistants", createAssistant);
|
|
10806
10933
|
app2.put("/api/assistants/:id", updateAssistant);
|