@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.mjs
CHANGED
|
@@ -692,6 +692,125 @@ var getAgentGraph = async (request, reply) => {
|
|
|
692
692
|
});
|
|
693
693
|
}
|
|
694
694
|
};
|
|
695
|
+
var STATS_CACHE_TTL_MS = 5 * 60 * 1e3;
|
|
696
|
+
var statsCache = /* @__PURE__ */ new Map();
|
|
697
|
+
async function getAssistantStats(request, reply) {
|
|
698
|
+
const tenantId = getTenantId(request);
|
|
699
|
+
const cached = statsCache.get(tenantId);
|
|
700
|
+
if (cached && cached.expiresAt > Date.now()) {
|
|
701
|
+
return {
|
|
702
|
+
success: true,
|
|
703
|
+
message: "Ok (cached)",
|
|
704
|
+
data: cached.data,
|
|
705
|
+
cache: {
|
|
706
|
+
expiresAt: new Date(cached.expiresAt).toISOString(),
|
|
707
|
+
remainingMs: cached.expiresAt - Date.now(),
|
|
708
|
+
cached: true
|
|
709
|
+
}
|
|
710
|
+
};
|
|
711
|
+
}
|
|
712
|
+
try {
|
|
713
|
+
const agentConfigs = await agentLatticeManager.getAllAgentConfigsByTenant(tenantId);
|
|
714
|
+
const codeConfiguredAssistants = agentConfigs.map(convertAgentConfigToAssistant);
|
|
715
|
+
const storeLattice = getStoreLattice("default", "assistant");
|
|
716
|
+
const assistantStore = storeLattice.store;
|
|
717
|
+
const storedAssistants = await assistantStore.getAllAssistants(tenantId);
|
|
718
|
+
const assistantMap = /* @__PURE__ */ new Map();
|
|
719
|
+
codeConfiguredAssistants.forEach((a) => assistantMap.set(a.id, a));
|
|
720
|
+
storedAssistants.forEach((a) => assistantMap.set(a.id, a));
|
|
721
|
+
const userId = getUserId(request);
|
|
722
|
+
const assistants = Array.from(assistantMap.values()).filter((a) => {
|
|
723
|
+
if (!a.ownerUserId) return true;
|
|
724
|
+
return a.ownerUserId === userId;
|
|
725
|
+
});
|
|
726
|
+
const threadStore = getStoreLattice("default", "thread").store;
|
|
727
|
+
const evalStore = getStoreLattice("default", "eval").store;
|
|
728
|
+
const now = Date.now();
|
|
729
|
+
const ms7d = 7 * 864e5;
|
|
730
|
+
const ms30d = 30 * 864e5;
|
|
731
|
+
const records = await Promise.all(
|
|
732
|
+
assistants.map(async (assistant) => {
|
|
733
|
+
let threadCount = 0;
|
|
734
|
+
let last7d = 0;
|
|
735
|
+
let last30d = 0;
|
|
736
|
+
let lastActive = null;
|
|
737
|
+
const daily7d = new Array(7).fill(0);
|
|
738
|
+
const daily30d = new Array(30).fill(0);
|
|
739
|
+
try {
|
|
740
|
+
const threads = await threadStore.getThreadsByAssistantId(tenantId, assistant.id);
|
|
741
|
+
threadCount = threads.length;
|
|
742
|
+
for (const t of threads) {
|
|
743
|
+
const created = new Date(t.createdAt).getTime();
|
|
744
|
+
if (created >= now - ms7d) last7d++;
|
|
745
|
+
if (created >= now - ms30d) last30d++;
|
|
746
|
+
const idx7 = Math.floor((now - created) / 864e5);
|
|
747
|
+
if (idx7 >= 0 && idx7 < 7) daily7d[6 - idx7]++;
|
|
748
|
+
const idx30 = Math.floor((now - created) / 864e5);
|
|
749
|
+
if (idx30 >= 0 && idx30 < 30) daily30d[29 - idx30]++;
|
|
750
|
+
const updated = new Date(t.updatedAt).getTime();
|
|
751
|
+
if (lastActive === null || updated > lastActive.getTime()) {
|
|
752
|
+
lastActive = new Date(t.updatedAt);
|
|
753
|
+
}
|
|
754
|
+
}
|
|
755
|
+
} catch {
|
|
756
|
+
}
|
|
757
|
+
let evalScore = null;
|
|
758
|
+
let evalPassRate = null;
|
|
759
|
+
let evalRuns = 0;
|
|
760
|
+
let evalTrend = [];
|
|
761
|
+
try {
|
|
762
|
+
const projects = await evalStore.getProjectsByTenant(tenantId);
|
|
763
|
+
const project = projects.find((p) => p.name === `eval-${assistant.id}`);
|
|
764
|
+
if (project) {
|
|
765
|
+
const runs = await evalStore.getRunsByTenant(tenantId, { projectId: project.id });
|
|
766
|
+
evalRuns = runs.length;
|
|
767
|
+
const sorted = [...runs].sort(
|
|
768
|
+
(a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime()
|
|
769
|
+
);
|
|
770
|
+
evalTrend = sorted.map((r) => typeof r.avgScore === "number" ? r.avgScore : null).filter((v) => v !== null);
|
|
771
|
+
const latest = sorted[sorted.length - 1];
|
|
772
|
+
if (latest) {
|
|
773
|
+
evalScore = typeof latest.avgScore === "number" ? latest.avgScore : null;
|
|
774
|
+
if (latest.totalCases > 0) {
|
|
775
|
+
evalPassRate = Math.round(latest.passedCases / latest.totalCases * 100);
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
}
|
|
779
|
+
} catch {
|
|
780
|
+
}
|
|
781
|
+
return {
|
|
782
|
+
id: assistant.id,
|
|
783
|
+
threadCount,
|
|
784
|
+
last7d,
|
|
785
|
+
last30d,
|
|
786
|
+
lastActive: lastActive ? lastActive.toISOString() : null,
|
|
787
|
+
daily7d,
|
|
788
|
+
daily30d,
|
|
789
|
+
evalScore,
|
|
790
|
+
evalPassRate,
|
|
791
|
+
evalRuns,
|
|
792
|
+
evalTrend: evalTrend.slice(-8)
|
|
793
|
+
};
|
|
794
|
+
})
|
|
795
|
+
);
|
|
796
|
+
const payload = { records };
|
|
797
|
+
const expiresAt = Date.now() + STATS_CACHE_TTL_MS;
|
|
798
|
+
statsCache.set(tenantId, { data: payload, expiresAt });
|
|
799
|
+
return {
|
|
800
|
+
success: true,
|
|
801
|
+
message: "Ok",
|
|
802
|
+
data: payload,
|
|
803
|
+
cache: {
|
|
804
|
+
expiresAt: new Date(expiresAt).toISOString(),
|
|
805
|
+
remainingMs: STATS_CACHE_TTL_MS,
|
|
806
|
+
cached: false
|
|
807
|
+
}
|
|
808
|
+
};
|
|
809
|
+
} catch (err) {
|
|
810
|
+
const message = err instanceof Error ? err.message : "Failed to get assistant stats";
|
|
811
|
+
return reply.status(500).send({ success: false, message });
|
|
812
|
+
}
|
|
813
|
+
}
|
|
695
814
|
|
|
696
815
|
// src/controllers/run.ts
|
|
697
816
|
import { v4 } from "uuid";
|
|
@@ -3376,6 +3495,7 @@ async function listTasks(request, reply) {
|
|
|
3376
3495
|
priority: query.priority,
|
|
3377
3496
|
...query.ownerId && { ownerId: query.ownerId },
|
|
3378
3497
|
...query.ownerType && { ownerType: query.ownerType },
|
|
3498
|
+
...query.parentId && { parentId: query.parentId },
|
|
3379
3499
|
metadata: query.metadata ? JSON.parse(query.metadata) : void 0,
|
|
3380
3500
|
projectId: query.projectId,
|
|
3381
3501
|
limit: query.limit ? parseInt(query.limit) : void 0,
|
|
@@ -6214,7 +6334,7 @@ var EvalRunner = class {
|
|
|
6214
6334
|
getEventEmitter() {
|
|
6215
6335
|
return this.eventEmitter;
|
|
6216
6336
|
}
|
|
6217
|
-
async startRun(tenantId, projectId, suiteIds, caseIds, runConfig) {
|
|
6337
|
+
async startRun(tenantId, projectId, suiteIds, caseIds, runConfig, taskId) {
|
|
6218
6338
|
const store = this.getEvalStore();
|
|
6219
6339
|
const project = await store.getProjectById(tenantId, projectId);
|
|
6220
6340
|
if (!project) throw new Error("Project not found");
|
|
@@ -6285,12 +6405,15 @@ var EvalRunner = class {
|
|
|
6285
6405
|
}
|
|
6286
6406
|
resolvedJudgeModelKey = judgeModelKey;
|
|
6287
6407
|
} else {
|
|
6288
|
-
const
|
|
6289
|
-
|
|
6408
|
+
const models = modelLatticeManager2.getAllLattices();
|
|
6409
|
+
const defaultModel = models.find((m) => m.key === "default");
|
|
6410
|
+
resolvedJudgeModelKey = defaultModel?.key ?? models[0]?.key ?? "";
|
|
6411
|
+
if (!resolvedJudgeModelKey) {
|
|
6290
6412
|
throw new Error("No model registered \u2014 cannot run eval without a judge model");
|
|
6291
6413
|
}
|
|
6292
|
-
|
|
6293
|
-
|
|
6414
|
+
if (!defaultModel) {
|
|
6415
|
+
console.warn(`[eval-runner] Project "${project.name}" has no judge modelKey and no "default" model \u2014 falling back to first registered model "${resolvedJudgeModelKey}"`);
|
|
6416
|
+
}
|
|
6294
6417
|
}
|
|
6295
6418
|
const runId = uuidv43();
|
|
6296
6419
|
const concurrency = Math.max(1, Math.floor(project.concurrency) || 3);
|
|
@@ -6302,7 +6425,8 @@ var EvalRunner = class {
|
|
|
6302
6425
|
concurrency,
|
|
6303
6426
|
holdout: isHoldout,
|
|
6304
6427
|
envWorkspaceId: workspaceId || void 0,
|
|
6305
|
-
envProjectId: projectIdFromConfig || void 0
|
|
6428
|
+
envProjectId: projectIdFromConfig || void 0,
|
|
6429
|
+
taskId
|
|
6306
6430
|
});
|
|
6307
6431
|
const projectConfig = {
|
|
6308
6432
|
projectName: project.name,
|
|
@@ -6409,7 +6533,7 @@ var EvalRunner = class {
|
|
|
6409
6533
|
this.runs.delete(runId);
|
|
6410
6534
|
}
|
|
6411
6535
|
})();
|
|
6412
|
-
this.runs.set(runId, { runId, projectId, tenantId, abortController, promise: runPromise });
|
|
6536
|
+
this.runs.set(runId, { runId, projectId, tenantId, abortController, promise: runPromise, taskId });
|
|
6413
6537
|
runPromise.catch(() => {
|
|
6414
6538
|
});
|
|
6415
6539
|
return runId;
|
|
@@ -6480,7 +6604,9 @@ async function createProject(request, reply) {
|
|
|
6480
6604
|
},
|
|
6481
6605
|
targetServerConfig: {
|
|
6482
6606
|
base_url: serverCfg.base_url || "",
|
|
6483
|
-
api_key: serverCfg.api_key || ""
|
|
6607
|
+
api_key: serverCfg.api_key || "",
|
|
6608
|
+
// Project↔agent association pointer (see manage_eval create_project).
|
|
6609
|
+
...serverCfg.targetAgentId ? { targetAgentId: serverCfg.targetAgentId } : {}
|
|
6484
6610
|
},
|
|
6485
6611
|
concurrency: data.concurrency ?? 1,
|
|
6486
6612
|
reportConfig: data.reportConfig
|
|
@@ -6789,7 +6915,7 @@ function registerEvalRoutes(app2) {
|
|
|
6789
6915
|
workspaceId: body?.runConfig?.workspaceId ?? bodyWs,
|
|
6790
6916
|
projectId: body?.runConfig?.projectId ?? bodyPj
|
|
6791
6917
|
};
|
|
6792
|
-
const runId = await evalRunner.startRun(tenantId, pid, body?.suiteIds, body?.caseIds, runConfig);
|
|
6918
|
+
const runId = await evalRunner.startRun(tenantId, pid, body?.suiteIds, body?.caseIds, runConfig, body?.taskId);
|
|
6793
6919
|
reply.status(202).send({ success: true, message: "Run started", data: { run_id: runId } });
|
|
6794
6920
|
} catch (err) {
|
|
6795
6921
|
const msg = err.message;
|
|
@@ -8792,6 +8918,7 @@ var registerLatticeRoutes = (app2, channelDeps) => {
|
|
|
8792
8918
|
clearMemory
|
|
8793
8919
|
);
|
|
8794
8920
|
app2.get("/api/assistants", getAssistantList);
|
|
8921
|
+
app2.get("/api/assistants/stats", getAssistantStats);
|
|
8795
8922
|
app2.get("/api/assistants/:id", getAssistant);
|
|
8796
8923
|
app2.post("/api/assistants", createAssistant);
|
|
8797
8924
|
app2.put("/api/assistants/:id", updateAssistant);
|