@axiom-lattice/gateway 4.6.1 → 4.8.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.
- package/dist/OrphanRecoveryRuntime-BEFILJMU.mjs +8 -0
- package/dist/RecoveryCallerDeps-6SJUYJ5S.mjs +8 -0
- package/dist/RecoveryCallerDeps-6SJUYJ5S.mjs.map +1 -0
- package/dist/{a2a-standard-PIOKEHPS.mjs → a2a-standard-PBYPNHOA.mjs} +59 -21
- package/dist/a2a-standard-PBYPNHOA.mjs.map +1 -0
- package/dist/{chunk-2POW27EI.mjs → chunk-7CG57LEF.mjs} +2 -2
- package/dist/{chunk-WKNZ7GBC.mjs → chunk-EXPERMZR.mjs} +1 -1
- package/dist/chunk-EXPERMZR.mjs.map +1 -0
- package/dist/{chunk-52SUWMOX.mjs → chunk-JUA3VJE7.mjs} +3 -2
- package/dist/chunk-JUA3VJE7.mjs.map +1 -0
- package/dist/chunk-NOXGKYUV.mjs +37 -0
- package/dist/chunk-NOXGKYUV.mjs.map +1 -0
- package/dist/{chunk-526UYVNQ.mjs → chunk-NPHK4SZ6.mjs} +4 -4
- package/dist/{chunk-TJAUXMYJ.mjs → chunk-URXZPI2F.mjs} +8 -1
- package/dist/chunk-URXZPI2F.mjs.map +1 -0
- package/dist/chunk-ZBTG3T7K.mjs +324 -0
- package/dist/chunk-ZBTG3T7K.mjs.map +1 -0
- package/dist/embed/{embed-page-AgentDetailSideApp-7NYLPLAX.js → embed-page-AgentDetailSideApp-NTLAFO5C.js} +1 -1
- package/dist/embed/{embed-page-AgentGovernanceWorkbench-LNGNSI7X.js → embed-page-AgentGovernanceWorkbench-QPVBOMLH.js} +1 -1
- package/dist/embed/{embed-page-MessageGraph-E6DZDT65.js → embed-page-MessageGraph-JAJGMYKH.js} +1 -1
- package/dist/embed/{embed-page-ReactChart-3VE7F5VJ.js → embed-page-ReactChart-WUG6TEAZ.js} +1 -1
- package/dist/embed/{embed-page-SkillFlow-XMMHEHQL.js → embed-page-SkillFlow-TSBZ4V2P.js} +1 -1
- package/dist/embed/{embed-page-TasksSideApp-QM5TZ7EG.js → embed-page-TasksSideApp-TJI22YGD.js} +1 -1
- package/dist/embed/{embed-page-TeamWorkspace-E7RFY3ZY.js → embed-page-TeamWorkspace-OJJLN5VI.js} +1 -1
- package/dist/embed/{embed-page-TopologyRuntimeView-DLPDUB7Z.js → embed-page-TopologyRuntimeView-ZFU4N6TV.js} +1 -1
- package/dist/embed/{embed-page-WorkflowAutomationView-FKSVOHHB.js → embed-page-WorkflowAutomationView-ALXV7VQQ.js} +1 -1
- package/dist/embed/{embed-page-chunk-I7PWCKAG.js → embed-page-chunk-DZQBVJ7Z.js} +1 -1
- package/dist/embed/{embed-page-chunk-WWTU55RX.js → embed-page-chunk-IPIJ2SG6.js} +1 -1
- package/dist/embed/{embed-page-chunk-KN7D66KL.js → embed-page-chunk-N22EGQAJ.js} +1 -1
- package/dist/embed/{embed-page-chunk-EXCJ42IB.js → embed-page-chunk-O72XBKQH.js} +2 -2
- package/dist/embed/{embed-page-chunk-U276WBDI.js → embed-page-chunk-QMVIL4BJ.js} +190 -185
- package/dist/embed/{embed-page-chunk-H6TK3FAR.js → embed-page-chunk-UT3WYBZH.js} +1 -1
- package/dist/embed/embed-page-chunk-YPNSOZYW.js +8 -0
- package/dist/embed/embed-page.js +1 -1
- package/dist/index.d.mts +362 -10
- package/dist/index.d.ts +362 -10
- package/dist/index.js +1693 -450
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +714 -154
- package/dist/index.mjs.map +1 -1
- package/dist/{open-AMEMJOFJ.mjs → open-UVKMONVE.mjs} +10 -9
- package/dist/open-UVKMONVE.mjs.map +1 -0
- package/dist/{open-exposure-I44Q4M3T.mjs → open-exposure-VU227IO3.mjs} +5 -5
- package/dist/{open-files-EJ6O2SGX.mjs → open-files-X3HXVEEM.mjs} +6 -6
- package/dist/{open-session-LBTCU3AE.mjs → open-session-2Y7XJJW2.mjs} +6 -6
- package/dist/{resources-DXPXAXEZ.mjs → resources-2L3KSUUU.mjs} +2 -2
- package/dist/sandboxOpenCredentialProvider-USIU7Z7H.mjs +275 -0
- package/dist/sandboxOpenCredentialProvider-USIU7Z7H.mjs.map +1 -0
- package/dist/{sandboxProvider-I3P66VXT.mjs → sandboxProvider-DUYWHYJN.mjs} +2 -2
- package/dist/sandboxProvider-DUYWHYJN.mjs.map +1 -0
- package/package.json +14 -8
- package/dist/a2a-standard-PIOKEHPS.mjs.map +0 -1
- package/dist/chunk-52SUWMOX.mjs.map +0 -1
- package/dist/chunk-TJAUXMYJ.mjs.map +0 -1
- package/dist/chunk-WKNZ7GBC.mjs.map +0 -1
- package/dist/embed/embed-page-chunk-HEMNMC4X.js +0 -7
- package/dist/open-AMEMJOFJ.mjs.map +0 -1
- /package/dist/{sandboxProvider-I3P66VXT.mjs.map → OrphanRecoveryRuntime-BEFILJMU.mjs.map} +0 -0
- /package/dist/{chunk-2POW27EI.mjs.map → chunk-7CG57LEF.mjs.map} +0 -0
- /package/dist/{chunk-526UYVNQ.mjs.map → chunk-NPHK4SZ6.mjs.map} +0 -0
- /package/dist/{open-exposure-I44Q4M3T.mjs.map → open-exposure-VU227IO3.mjs.map} +0 -0
- /package/dist/{open-files-EJ6O2SGX.mjs.map → open-files-X3HXVEEM.mjs.map} +0 -0
- /package/dist/{open-session-LBTCU3AE.mjs.map → open-session-2Y7XJJW2.mjs.map} +0 -0
- /package/dist/{resources-DXPXAXEZ.mjs.map → resources-2L3KSUUU.mjs.map} +0 -0
package/dist/index.js
CHANGED
|
@@ -874,6 +874,44 @@ var init_wechat_client = __esm({
|
|
|
874
874
|
}
|
|
875
875
|
});
|
|
876
876
|
|
|
877
|
+
// src/services/collaboration/projectTaskScope.ts
|
|
878
|
+
function isProjectLifecycleTask(task) {
|
|
879
|
+
const source = task.context?.source;
|
|
880
|
+
return typeof task.workspaceId === "string" && task.workspaceId.length > 0 && typeof task.projectId === "string" && task.projectId.length > 0 && (source === "project_room" || source === "project_task" || source === "user");
|
|
881
|
+
}
|
|
882
|
+
function isRosterExemptProject(project) {
|
|
883
|
+
return project?.kind === "public";
|
|
884
|
+
}
|
|
885
|
+
function resolveTaskOwnerMembership(task, project, room, membership) {
|
|
886
|
+
const active = membership && membership.status === "active" && membership.tenantId === task.tenantId && membership.workspaceId === task.workspaceId && membership.projectId === task.projectId && membership.assistantId === task.ownerId && membership.roomId === room.id;
|
|
887
|
+
if (active) return membership;
|
|
888
|
+
if (!isRosterExemptProject(project)) return void 0;
|
|
889
|
+
return syntheticPublicProjectOwnerMembership(task, room);
|
|
890
|
+
}
|
|
891
|
+
function syntheticPublicProjectOwnerMembership(task, room) {
|
|
892
|
+
const threadId = typeof task.context?.thread_id === "string" && task.context.thread_id.length > 0 ? task.context.thread_id : task.ownerId;
|
|
893
|
+
return {
|
|
894
|
+
id: `public-project-owner:${task.projectId}:${task.ownerId}`,
|
|
895
|
+
tenantId: task.tenantId,
|
|
896
|
+
workspaceId: task.workspaceId,
|
|
897
|
+
projectId: task.projectId,
|
|
898
|
+
roomId: room.id,
|
|
899
|
+
assistantId: task.ownerId,
|
|
900
|
+
role: "specialist",
|
|
901
|
+
title: task.ownerId,
|
|
902
|
+
mentionName: task.ownerId,
|
|
903
|
+
status: "active",
|
|
904
|
+
roomThreadId: threadId,
|
|
905
|
+
joinedAt: task.createdAt,
|
|
906
|
+
updatedAt: task.updatedAt
|
|
907
|
+
};
|
|
908
|
+
}
|
|
909
|
+
var init_projectTaskScope = __esm({
|
|
910
|
+
"src/services/collaboration/projectTaskScope.ts"() {
|
|
911
|
+
"use strict";
|
|
912
|
+
}
|
|
913
|
+
});
|
|
914
|
+
|
|
877
915
|
// src/services/files/task-file-refs.ts
|
|
878
916
|
function formatFileRefsSection(refs) {
|
|
879
917
|
const lines = refs.map((ref) => {
|
|
@@ -889,6 +927,336 @@ var init_task_file_refs = __esm({
|
|
|
889
927
|
}
|
|
890
928
|
});
|
|
891
929
|
|
|
930
|
+
// src/services/collaboration/TopCallerRecovery.ts
|
|
931
|
+
function hasPendingInterrupts(state) {
|
|
932
|
+
return (state.tasks ?? []).some((t2) => (t2.interrupts?.length ?? 0) > 0);
|
|
933
|
+
}
|
|
934
|
+
function pendingTaskCalls(state) {
|
|
935
|
+
const messages = state.values?.messages ?? [];
|
|
936
|
+
const resolved = new Set(
|
|
937
|
+
messages.filter((m) => m.tool_call_id).map((m) => m.tool_call_id)
|
|
938
|
+
);
|
|
939
|
+
const calls = [];
|
|
940
|
+
for (const m of messages) {
|
|
941
|
+
const typed = m;
|
|
942
|
+
if (typeof typed.getType !== "function" || typed.getType() !== "ai") continue;
|
|
943
|
+
const toolCalls = m.tool_calls;
|
|
944
|
+
if (!Array.isArray(toolCalls)) continue;
|
|
945
|
+
for (const c2 of toolCalls) {
|
|
946
|
+
if (c2.name !== "task" || !c2.id || resolved.has(c2.id)) continue;
|
|
947
|
+
const taskId = typeof c2.args?.taskId === "string" ? c2.args.taskId : void 0;
|
|
948
|
+
calls.push({ id: c2.id, ...taskId ? { taskId } : {} });
|
|
949
|
+
}
|
|
950
|
+
}
|
|
951
|
+
return calls;
|
|
952
|
+
}
|
|
953
|
+
function outcome(task) {
|
|
954
|
+
if (task.status === "completed") {
|
|
955
|
+
return JSON.stringify({ success: true, taskId: task.id, result: task.result ?? "" });
|
|
956
|
+
}
|
|
957
|
+
if (task.status === "failed") {
|
|
958
|
+
return JSON.stringify({ success: false, code: "TASK_FAILED", retryable: false, taskId: task.id, error: task.failureReason ?? "" });
|
|
959
|
+
}
|
|
960
|
+
return JSON.stringify({
|
|
961
|
+
success: false,
|
|
962
|
+
code: "TASK_INTERRUPTED",
|
|
963
|
+
retryable: false,
|
|
964
|
+
taskId: task.id,
|
|
965
|
+
error: "Run ended before completion; the task is interrupted and awaiting a decision."
|
|
966
|
+
});
|
|
967
|
+
}
|
|
968
|
+
async function backfillTopCallerGroup(tasks, top, deps) {
|
|
969
|
+
const registry = deps.registry ?? import_core70.taskRunRegistry;
|
|
970
|
+
const results = [];
|
|
971
|
+
const eligible = [];
|
|
972
|
+
for (const task of tasks) {
|
|
973
|
+
if (!task.context?.caller_thread_id) {
|
|
974
|
+
results.push({ id: task.id, reason: "skipped:no_caller_link" });
|
|
975
|
+
continue;
|
|
976
|
+
}
|
|
977
|
+
if (registry.isLive(task.id) || deps.isTaskLive && await deps.isTaskLive(task)) {
|
|
978
|
+
results.push({ id: task.id, reason: "skipped:live" });
|
|
979
|
+
continue;
|
|
980
|
+
}
|
|
981
|
+
eligible.push(task);
|
|
982
|
+
}
|
|
983
|
+
if (eligible.length === 0) return results;
|
|
984
|
+
const target = await deps.callerFor(top, eligible[0].tenantId);
|
|
985
|
+
if (!target) {
|
|
986
|
+
return [...results, ...eligible.map((task) => ({ id: task.id, reason: "skipped:no_caller_client" }))];
|
|
987
|
+
}
|
|
988
|
+
const state = await target.client.getState(target.config);
|
|
989
|
+
if (hasPendingInterrupts(state)) {
|
|
990
|
+
return [...results, ...eligible.map((task) => ({ id: task.id, reason: "skipped:hitl" }))];
|
|
991
|
+
}
|
|
992
|
+
const nodeName = (state.tasks ?? [])[0]?.name;
|
|
993
|
+
if (!nodeName) {
|
|
994
|
+
return [...results, ...eligible.map((task) => ({ id: task.id, reason: "skipped:no_pending_node" }))];
|
|
995
|
+
}
|
|
996
|
+
const calls = pendingTaskCalls(state);
|
|
997
|
+
const matched = [];
|
|
998
|
+
for (const task of eligible) {
|
|
999
|
+
const call = calls.find((candidate) => candidate.taskId === task.id);
|
|
1000
|
+
if (!call) {
|
|
1001
|
+
results.push({ id: task.id, reason: "skipped:no_pending_task_call" });
|
|
1002
|
+
continue;
|
|
1003
|
+
}
|
|
1004
|
+
matched.push({ task, call });
|
|
1005
|
+
}
|
|
1006
|
+
if (matched.length === 0) return results;
|
|
1007
|
+
await target.client.updateState(target.config, {
|
|
1008
|
+
messages: matched.map(({ task, call }) => new import_messages.ToolMessage({ content: outcome(task), tool_call_id: call.id, name: "task" }))
|
|
1009
|
+
}, nodeName);
|
|
1010
|
+
await deps.resume(target.client, target.config, target.agent);
|
|
1011
|
+
return [...results, ...matched.map(({ task }) => ({ id: task.id, reason: "recovered" }))];
|
|
1012
|
+
}
|
|
1013
|
+
async function recoverTopCaller(task, top, deps) {
|
|
1014
|
+
if (!task.context?.caller_thread_id) return "skipped:no_caller_link";
|
|
1015
|
+
if (task.context.caller_thread_id !== top.threadId) return "skipped:middle";
|
|
1016
|
+
const [first] = await backfillTopCallerGroup([task], top, deps);
|
|
1017
|
+
return first?.reason ?? "skipped:no_pending_task_call";
|
|
1018
|
+
}
|
|
1019
|
+
async function recoverTask(task, deps) {
|
|
1020
|
+
if (task.status !== "in_progress") {
|
|
1021
|
+
return { kind: "skipped", reason: "not_in_progress" };
|
|
1022
|
+
}
|
|
1023
|
+
const registry = deps.registry ?? import_core70.taskRunRegistry;
|
|
1024
|
+
if (registry.isLive(task.id) || deps.isTaskLive && await deps.isTaskLive(task)) {
|
|
1025
|
+
return { kind: "skipped", reason: "live" };
|
|
1026
|
+
}
|
|
1027
|
+
const { convergedTasks } = await (0, import_core70.reconcileStaleTaskRuns)({
|
|
1028
|
+
tasks: [task],
|
|
1029
|
+
actor: "system:on-demand-recovery",
|
|
1030
|
+
lifecycle: deps.lifecycle,
|
|
1031
|
+
...deps.registry ? { registry: deps.registry } : {},
|
|
1032
|
+
...deps.isTaskLive ? { isTaskLive: deps.isTaskLive } : {}
|
|
1033
|
+
});
|
|
1034
|
+
const converged = convergedTasks[0];
|
|
1035
|
+
if (!converged) {
|
|
1036
|
+
return { kind: "skipped", reason: "convergence_failed" };
|
|
1037
|
+
}
|
|
1038
|
+
const top = resolveTopCaller(converged, deps.orphans ?? [converged]);
|
|
1039
|
+
if (!top) {
|
|
1040
|
+
return { kind: "skipped", reason: "no_top_caller" };
|
|
1041
|
+
}
|
|
1042
|
+
if (converged.context?.caller_thread_id !== top.threadId) {
|
|
1043
|
+
return { kind: "skipped", reason: "middle" };
|
|
1044
|
+
}
|
|
1045
|
+
const reason = await recoverTopCaller(converged, top, {
|
|
1046
|
+
callerFor: deps.callerFor,
|
|
1047
|
+
resume: deps.resume,
|
|
1048
|
+
...deps.registry ? { registry: deps.registry } : {},
|
|
1049
|
+
...deps.isTaskLive ? { isTaskLive: deps.isTaskLive } : {}
|
|
1050
|
+
});
|
|
1051
|
+
if (reason === "recovered") return { kind: "recovered" };
|
|
1052
|
+
if (reason === "skipped:no_pending_task_call") return { kind: "converged_no_call" };
|
|
1053
|
+
return { kind: "skipped", reason: reason.replace(/^skipped:/, "") };
|
|
1054
|
+
}
|
|
1055
|
+
function resolveTopCaller(task, orphans) {
|
|
1056
|
+
const tenantId = task.tenantId;
|
|
1057
|
+
const runThreadToTask = new Map(
|
|
1058
|
+
orphans.map((orphan) => [`${orphan.tenantId}:${orphan.context?.thread_id}`, orphan])
|
|
1059
|
+
);
|
|
1060
|
+
let threadId = task.context?.caller_thread_id;
|
|
1061
|
+
let assistantId = task.context?.caller_assistant_id;
|
|
1062
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1063
|
+
while (threadId) {
|
|
1064
|
+
const scopeKey3 = `${tenantId}:${threadId}`;
|
|
1065
|
+
if (!runThreadToTask.has(scopeKey3) || seen.has(scopeKey3)) break;
|
|
1066
|
+
seen.add(scopeKey3);
|
|
1067
|
+
const parent = runThreadToTask.get(scopeKey3);
|
|
1068
|
+
threadId = parent.context?.caller_thread_id;
|
|
1069
|
+
assistantId = parent.context?.caller_assistant_id;
|
|
1070
|
+
}
|
|
1071
|
+
return threadId ? { threadId, ...assistantId ? { assistantId } : {} } : void 0;
|
|
1072
|
+
}
|
|
1073
|
+
async function runOrphanRecovery(deps) {
|
|
1074
|
+
let convergedTasks;
|
|
1075
|
+
try {
|
|
1076
|
+
({ convergedTasks } = await deps.reconcile());
|
|
1077
|
+
} catch (error) {
|
|
1078
|
+
deps.log.warn("Task orphan recovery reconcile failed", {
|
|
1079
|
+
error: error instanceof Error ? error.message : String(error)
|
|
1080
|
+
});
|
|
1081
|
+
return { recovered: [], skipped: ["reconcile:error"] };
|
|
1082
|
+
}
|
|
1083
|
+
const orphans = convergedTasks;
|
|
1084
|
+
const recovered = [];
|
|
1085
|
+
const skipped = [];
|
|
1086
|
+
const groups = /* @__PURE__ */ new Map();
|
|
1087
|
+
for (const task of orphans) {
|
|
1088
|
+
const top = resolveTopCaller(task, orphans);
|
|
1089
|
+
if (!top) {
|
|
1090
|
+
skipped.push(`${task.id}:skipped:no_top_caller`);
|
|
1091
|
+
continue;
|
|
1092
|
+
}
|
|
1093
|
+
if (task.context?.caller_thread_id !== top.threadId) {
|
|
1094
|
+
skipped.push(`${task.id}:skipped:middle`);
|
|
1095
|
+
continue;
|
|
1096
|
+
}
|
|
1097
|
+
const key = `${task.tenantId}:${top.threadId}`;
|
|
1098
|
+
const group = groups.get(key);
|
|
1099
|
+
if (group) group.tasks.push(task);
|
|
1100
|
+
else groups.set(key, { top, tasks: [task] });
|
|
1101
|
+
}
|
|
1102
|
+
for (const { top, tasks } of groups.values()) {
|
|
1103
|
+
try {
|
|
1104
|
+
const results = await backfillTopCallerGroup(tasks, top, {
|
|
1105
|
+
callerFor: deps.callerFor,
|
|
1106
|
+
resume: deps.resume,
|
|
1107
|
+
...deps.isTaskLive ? { isTaskLive: deps.isTaskLive } : {}
|
|
1108
|
+
});
|
|
1109
|
+
for (const { id: id3, reason } of results) {
|
|
1110
|
+
(reason === "recovered" ? recovered : skipped).push(`${id3}:${reason}`);
|
|
1111
|
+
}
|
|
1112
|
+
} catch (error) {
|
|
1113
|
+
for (const task of tasks) skipped.push(`${task.id}:error`);
|
|
1114
|
+
deps.log.warn("Task orphan recovery group failed", {
|
|
1115
|
+
threadId: top.threadId,
|
|
1116
|
+
error: error instanceof Error ? error.message : String(error)
|
|
1117
|
+
});
|
|
1118
|
+
}
|
|
1119
|
+
}
|
|
1120
|
+
deps.log.info("Task orphan recovery complete", { recovered, skipped });
|
|
1121
|
+
return { recovered, skipped };
|
|
1122
|
+
}
|
|
1123
|
+
var import_messages, import_core70;
|
|
1124
|
+
var init_TopCallerRecovery = __esm({
|
|
1125
|
+
"src/services/collaboration/TopCallerRecovery.ts"() {
|
|
1126
|
+
"use strict";
|
|
1127
|
+
import_messages = require("@langchain/core/messages");
|
|
1128
|
+
import_core70 = require("@axiom-lattice/core");
|
|
1129
|
+
}
|
|
1130
|
+
});
|
|
1131
|
+
|
|
1132
|
+
// src/services/collaboration/taskRunLiveness.ts
|
|
1133
|
+
function createTaskRunLiveness() {
|
|
1134
|
+
try {
|
|
1135
|
+
import_core71.storeLatticeManager.getStoreLattice("default", "lease");
|
|
1136
|
+
} catch {
|
|
1137
|
+
return void 0;
|
|
1138
|
+
}
|
|
1139
|
+
return async (task) => {
|
|
1140
|
+
try {
|
|
1141
|
+
const store2 = import_core71.storeLatticeManager.getStoreLattice("default", "lease").store;
|
|
1142
|
+
if (await store2.get((0, import_core71.taskRunLeaseKey)(task.id))) return true;
|
|
1143
|
+
const threadId = typeof task.context?.thread_id === "string" ? task.context.thread_id : void 0;
|
|
1144
|
+
if (threadId && task.ownerId) {
|
|
1145
|
+
if (await store2.get((0, import_core71.threadRunLeaseKey)(task.tenantId, task.ownerId, threadId))) return true;
|
|
1146
|
+
}
|
|
1147
|
+
return false;
|
|
1148
|
+
} catch {
|
|
1149
|
+
return true;
|
|
1150
|
+
}
|
|
1151
|
+
};
|
|
1152
|
+
}
|
|
1153
|
+
var import_core71;
|
|
1154
|
+
var init_taskRunLiveness = __esm({
|
|
1155
|
+
"src/services/collaboration/taskRunLiveness.ts"() {
|
|
1156
|
+
"use strict";
|
|
1157
|
+
import_core71 = require("@axiom-lattice/core");
|
|
1158
|
+
}
|
|
1159
|
+
});
|
|
1160
|
+
|
|
1161
|
+
// src/services/collaboration/OrphanRecoveryRuntime.ts
|
|
1162
|
+
var OrphanRecoveryRuntime_exports = {};
|
|
1163
|
+
__export(OrphanRecoveryRuntime_exports, {
|
|
1164
|
+
createOrphanRecoveryRuntime: () => createOrphanRecoveryRuntime
|
|
1165
|
+
});
|
|
1166
|
+
function createOrphanRecoveryRuntime(deps) {
|
|
1167
|
+
const lifecycle = deps.lifecycle ?? (0, import_core72.createTaskLifecycleService)({
|
|
1168
|
+
taskStore: deps.taskStore,
|
|
1169
|
+
workItemStore: deps.workItemStore
|
|
1170
|
+
});
|
|
1171
|
+
return {
|
|
1172
|
+
async recoverAll() {
|
|
1173
|
+
const isTaskLive = deps.isTaskLive ?? createTaskRunLiveness();
|
|
1174
|
+
return runOrphanRecovery({
|
|
1175
|
+
reconcile: () => (0, import_core72.reconcileAllTenantTaskRuns)({
|
|
1176
|
+
actor: "system:orphan-recovery",
|
|
1177
|
+
tenantStore: {
|
|
1178
|
+
listTenants: async () => (await deps.tenantStore.getAllTenants()).map((tenant2) => ({ id: tenant2.id }))
|
|
1179
|
+
},
|
|
1180
|
+
taskStore: deps.taskStore,
|
|
1181
|
+
lifecycle,
|
|
1182
|
+
include: (t2) => !isProjectLifecycleTask(t2),
|
|
1183
|
+
...isTaskLive ? { isTaskLive } : {}
|
|
1184
|
+
}),
|
|
1185
|
+
callerFor: deps.callerFor,
|
|
1186
|
+
resume: deps.resume,
|
|
1187
|
+
...isTaskLive ? { isTaskLive } : {},
|
|
1188
|
+
log: deps.log
|
|
1189
|
+
});
|
|
1190
|
+
},
|
|
1191
|
+
async recoverTask(input) {
|
|
1192
|
+
const task = await deps.taskStore.getById(input.tenantId, input.taskId);
|
|
1193
|
+
if (!task) return { kind: "skipped", reason: "not_found" };
|
|
1194
|
+
if (isProjectLifecycleTask(task)) {
|
|
1195
|
+
return { kind: "skipped", reason: "project_task" };
|
|
1196
|
+
}
|
|
1197
|
+
const orphans = await deps.taskStore.list({ tenantId: input.tenantId, status: "in_progress" });
|
|
1198
|
+
const isTaskLive = deps.isTaskLive ?? createTaskRunLiveness();
|
|
1199
|
+
return recoverTask(task, {
|
|
1200
|
+
lifecycle,
|
|
1201
|
+
registry: import_core72.taskRunRegistry,
|
|
1202
|
+
orphans,
|
|
1203
|
+
callerFor: deps.callerFor,
|
|
1204
|
+
resume: deps.resume,
|
|
1205
|
+
...isTaskLive ? { isTaskLive } : {}
|
|
1206
|
+
});
|
|
1207
|
+
}
|
|
1208
|
+
};
|
|
1209
|
+
}
|
|
1210
|
+
var import_core72;
|
|
1211
|
+
var init_OrphanRecoveryRuntime = __esm({
|
|
1212
|
+
"src/services/collaboration/OrphanRecoveryRuntime.ts"() {
|
|
1213
|
+
"use strict";
|
|
1214
|
+
import_core72 = require("@axiom-lattice/core");
|
|
1215
|
+
init_TopCallerRecovery();
|
|
1216
|
+
init_projectTaskScope();
|
|
1217
|
+
init_taskRunLiveness();
|
|
1218
|
+
}
|
|
1219
|
+
});
|
|
1220
|
+
|
|
1221
|
+
// src/services/collaboration/RecoveryCallerDeps.ts
|
|
1222
|
+
var RecoveryCallerDeps_exports = {};
|
|
1223
|
+
__export(RecoveryCallerDeps_exports, {
|
|
1224
|
+
createRecoveryCallerDeps: () => createRecoveryCallerDeps
|
|
1225
|
+
});
|
|
1226
|
+
function createRecoveryCallerDeps() {
|
|
1227
|
+
return {
|
|
1228
|
+
callerFor: async (top, tenantId) => {
|
|
1229
|
+
if (!top.assistantId) return void 0;
|
|
1230
|
+
const load = import_core73.getAgentClientAsync ?? import_core73.getAgentClient;
|
|
1231
|
+
const client = await load(tenantId, top.assistantId);
|
|
1232
|
+
const config = { configurable: { thread_id: top.threadId, runConfig: { tenantId, assistant_id: top.assistantId } } };
|
|
1233
|
+
let agent;
|
|
1234
|
+
try {
|
|
1235
|
+
agent = import_core73.agentInstanceManager.getAgent({ assistant_id: top.assistantId, thread_id: top.threadId, tenant_id: tenantId });
|
|
1236
|
+
} catch {
|
|
1237
|
+
}
|
|
1238
|
+
return agent ? { client, config, agent } : { client, config };
|
|
1239
|
+
},
|
|
1240
|
+
resume: async (client, config, agent) => {
|
|
1241
|
+
if (agent && typeof agent.resumeTask === "function") {
|
|
1242
|
+
try {
|
|
1243
|
+
await agent.resumeTask();
|
|
1244
|
+
return;
|
|
1245
|
+
} catch {
|
|
1246
|
+
}
|
|
1247
|
+
}
|
|
1248
|
+
await client.invoke(null, config);
|
|
1249
|
+
}
|
|
1250
|
+
};
|
|
1251
|
+
}
|
|
1252
|
+
var import_core73;
|
|
1253
|
+
var init_RecoveryCallerDeps = __esm({
|
|
1254
|
+
"src/services/collaboration/RecoveryCallerDeps.ts"() {
|
|
1255
|
+
"use strict";
|
|
1256
|
+
import_core73 = require("@axiom-lattice/core");
|
|
1257
|
+
}
|
|
1258
|
+
});
|
|
1259
|
+
|
|
892
1260
|
// src/channels/wechat/context-store.ts
|
|
893
1261
|
function makeKey(installationId, senderId) {
|
|
894
1262
|
return `${installationId}::${senderId}`;
|
|
@@ -1179,11 +1547,11 @@ function devModeDefaults() {
|
|
|
1179
1547
|
const projectId = process.env[DEFAULT_PROJECT_ENV] || void 0;
|
|
1180
1548
|
return { tenantId, projectId };
|
|
1181
1549
|
}
|
|
1182
|
-
var
|
|
1550
|
+
var import_protocols34, A2AAuthError, DEFAULT_TENANT_ENV, DEFAULT_TENANT_ID, DEFAULT_PROJECT_ENV, BEARER_SCHEME_RE, A2AAuthService;
|
|
1183
1551
|
var init_A2AAuthService = __esm({
|
|
1184
1552
|
"src/services/a2a/A2AAuthService.ts"() {
|
|
1185
1553
|
"use strict";
|
|
1186
|
-
|
|
1554
|
+
import_protocols34 = require("@axiom-lattice/protocols");
|
|
1187
1555
|
A2AAuthError = class extends Error {
|
|
1188
1556
|
constructor(message, statusCode) {
|
|
1189
1557
|
super(message);
|
|
@@ -1238,7 +1606,7 @@ var init_A2AAuthService = __esm({
|
|
|
1238
1606
|
const entry = merged.get(token);
|
|
1239
1607
|
if (!entry) return { authenticated: false };
|
|
1240
1608
|
const hasExplicitGrants = Array.isArray(entry.grants) && entry.grants.length > 0;
|
|
1241
|
-
const agentGrant = (0,
|
|
1609
|
+
const agentGrant = (0, import_protocols34.effectiveGrants)(entry).find((g) => g.domain === "agent");
|
|
1242
1610
|
const assistantIds = hasExplicitGrants ? agentGrant?.items ?? [] : entry.assistantIds;
|
|
1243
1611
|
return {
|
|
1244
1612
|
authenticated: true,
|
|
@@ -1475,13 +1843,13 @@ function isA2ATaskSnapshot(value) {
|
|
|
1475
1843
|
function snapshotSequence(value) {
|
|
1476
1844
|
return typeof value === "number" && Number.isSafeInteger(value) && value >= 0 ? value : void 0;
|
|
1477
1845
|
}
|
|
1478
|
-
var import_node_crypto28, import_node_util,
|
|
1846
|
+
var import_node_crypto28, import_node_util, import_core74, TASK_STATUS_TO_A2A_STATE, TITLE_MAX_LENGTH, A2ATaskScopeConflictError, A2ATaskStoreAdapter;
|
|
1479
1847
|
var init_A2ATaskStoreAdapter = __esm({
|
|
1480
1848
|
"src/services/a2a/A2ATaskStoreAdapter.ts"() {
|
|
1481
1849
|
"use strict";
|
|
1482
1850
|
import_node_crypto28 = require("crypto");
|
|
1483
1851
|
import_node_util = require("util");
|
|
1484
|
-
|
|
1852
|
+
import_core74 = require("@axiom-lattice/core");
|
|
1485
1853
|
TASK_STATUS_TO_A2A_STATE = {
|
|
1486
1854
|
pending: "submitted",
|
|
1487
1855
|
in_progress: "working",
|
|
@@ -1507,7 +1875,7 @@ var init_A2ATaskStoreAdapter = __esm({
|
|
|
1507
1875
|
this.workItemStore = options.workItemStore;
|
|
1508
1876
|
this.lifecycle = options.lifecycle;
|
|
1509
1877
|
this.scope = options.scope;
|
|
1510
|
-
this.runBridge = (0,
|
|
1878
|
+
this.runBridge = (0, import_core74.createTaskRunBridge)({
|
|
1511
1879
|
lifecycle: this.lifecycle,
|
|
1512
1880
|
taskStore: this.taskStore,
|
|
1513
1881
|
workItemStore: this.workItemStore
|
|
@@ -1858,13 +2226,13 @@ function assistantHasGovernedTask(assistant) {
|
|
|
1858
2226
|
const allowedTools = taskMiddleware?.allowedTools;
|
|
1859
2227
|
return !!taskMiddleware && (allowedTools === void 0 || Array.isArray(allowedTools) && (allowedTools.length === 0 || allowedTools.includes("manage_task")));
|
|
1860
2228
|
}
|
|
1861
|
-
var import_uuid11,
|
|
2229
|
+
var import_uuid11, import_core75, import_protocols35, _AxiomAgentExecutor, AxiomAgentExecutor;
|
|
1862
2230
|
var init_AxiomAgentExecutor = __esm({
|
|
1863
2231
|
"src/services/a2a/AxiomAgentExecutor.ts"() {
|
|
1864
2232
|
"use strict";
|
|
1865
2233
|
import_uuid11 = require("uuid");
|
|
1866
|
-
|
|
1867
|
-
|
|
2234
|
+
import_core75 = require("@axiom-lattice/core");
|
|
2235
|
+
import_protocols35 = require("@axiom-lattice/protocols");
|
|
1868
2236
|
init_a2aFileRefs();
|
|
1869
2237
|
init_task_file_refs();
|
|
1870
2238
|
_AxiomAgentExecutor = class _AxiomAgentExecutor {
|
|
@@ -1897,16 +2265,31 @@ var init_AxiomAgentExecutor = __esm({
|
|
|
1897
2265
|
status: { state: "working", timestamp: isoNow() },
|
|
1898
2266
|
metadata: { threadId, dependencies, inputFiles }
|
|
1899
2267
|
});
|
|
1900
|
-
const
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
taskId: ctx.taskId,
|
|
1904
|
-
contextId: ctx.contextId,
|
|
2268
|
+
const failTask = async (baseTask, err) => {
|
|
2269
|
+
const failedTask = {
|
|
2270
|
+
...baseTask,
|
|
1905
2271
|
status: {
|
|
1906
2272
|
state: "failed",
|
|
1907
2273
|
message: agentMessage(err instanceof Error ? err.message : String(err)),
|
|
1908
2274
|
timestamp: isoNow()
|
|
1909
|
-
}
|
|
2275
|
+
}
|
|
2276
|
+
};
|
|
2277
|
+
if (this.taskStore) {
|
|
2278
|
+
try {
|
|
2279
|
+
await this.taskStore.save(failedTask);
|
|
2280
|
+
} catch (saveError) {
|
|
2281
|
+
console.warn({
|
|
2282
|
+
event: "a2a:settle:save_failed",
|
|
2283
|
+
taskId: ctx.taskId,
|
|
2284
|
+
error: saveError instanceof Error ? saveError.message : String(saveError)
|
|
2285
|
+
});
|
|
2286
|
+
}
|
|
2287
|
+
}
|
|
2288
|
+
bus.publish({
|
|
2289
|
+
kind: "status-update",
|
|
2290
|
+
taskId: ctx.taskId,
|
|
2291
|
+
contextId: ctx.contextId,
|
|
2292
|
+
status: failedTask.status,
|
|
1910
2293
|
final: true
|
|
1911
2294
|
});
|
|
1912
2295
|
};
|
|
@@ -1914,7 +2297,7 @@ var init_AxiomAgentExecutor = __esm({
|
|
|
1914
2297
|
if (!this.taskStore) {
|
|
1915
2298
|
const initialTask2 = createTask([]);
|
|
1916
2299
|
bus.publish(initialTask2);
|
|
1917
|
-
|
|
2300
|
+
await failTask(initialTask2, new Error("A2A execution requires a canonical task store"));
|
|
1918
2301
|
return;
|
|
1919
2302
|
}
|
|
1920
2303
|
const governed = this.hasGovernedTaskCapability();
|
|
@@ -1938,14 +2321,14 @@ var init_AxiomAgentExecutor = __esm({
|
|
|
1938
2321
|
const initialTask2 = createTask([]);
|
|
1939
2322
|
if (this.taskStore) await this.taskStore.save(initialTask2);
|
|
1940
2323
|
bus.publish(initialTask2);
|
|
1941
|
-
|
|
2324
|
+
await failTask(initialTask2, err);
|
|
1942
2325
|
return;
|
|
1943
2326
|
}
|
|
1944
2327
|
const initialTask = createTask(inputFiles);
|
|
1945
2328
|
await this.taskStore.save(initialTask);
|
|
1946
2329
|
bus.publish(initialTask);
|
|
1947
2330
|
try {
|
|
1948
|
-
const agent =
|
|
2331
|
+
const agent = import_core75.agentInstanceManager.getAgent(this.agentParams(threadId));
|
|
1949
2332
|
const requestText = inputFiles.length > 0 ? `${text}
|
|
1950
2333
|
|
|
1951
2334
|
${formatFileRefsSection(inputFiles)}` : text;
|
|
@@ -1963,7 +2346,7 @@ ${formatFileRefsSection(inputFiles)}` : text;
|
|
|
1963
2346
|
custom_run_config: { taskId: ctx.taskId, execution: { taskId: ctx.taskId } }
|
|
1964
2347
|
});
|
|
1965
2348
|
const stream = agent.chunkStream(messageId, [
|
|
1966
|
-
|
|
2349
|
+
import_protocols35.MessageChunkTypes.MESSAGE_COMPLETED
|
|
1967
2350
|
]);
|
|
1968
2351
|
let outputText = "";
|
|
1969
2352
|
let interrupted = false;
|
|
@@ -1971,14 +2354,14 @@ ${formatFileRefsSection(inputFiles)}` : text;
|
|
|
1971
2354
|
if (execution.canceled) return;
|
|
1972
2355
|
const chunkType = chunk.type;
|
|
1973
2356
|
const chunkText = chunk.data?.content ?? "";
|
|
1974
|
-
if (chunkType ===
|
|
2357
|
+
if (chunkType === import_protocols35.MessageChunkTypes.INTERRUPT) {
|
|
1975
2358
|
interrupted = true;
|
|
1976
2359
|
break;
|
|
1977
2360
|
}
|
|
1978
|
-
if (chunkType ===
|
|
2361
|
+
if (chunkType === import_protocols35.MessageChunkTypes.AI && chunkText) {
|
|
1979
2362
|
outputText += chunkText;
|
|
1980
2363
|
}
|
|
1981
|
-
if (chunkType ===
|
|
2364
|
+
if (chunkType === import_protocols35.MessageChunkTypes.AI || chunkType === import_protocols35.MessageChunkTypes.TOOL) {
|
|
1982
2365
|
if (chunkText) {
|
|
1983
2366
|
bus.publish({
|
|
1984
2367
|
kind: "status-update",
|
|
@@ -2081,19 +2464,12 @@ ${formatFileRefsSection(inputFiles)}` : text;
|
|
|
2081
2464
|
});
|
|
2082
2465
|
return;
|
|
2083
2466
|
}
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
status: {
|
|
2089
|
-
state: "failed",
|
|
2090
|
-
message: agentMessage("Agent did not complete governed task lifecycle"),
|
|
2091
|
-
timestamp: isoNow()
|
|
2092
|
-
},
|
|
2093
|
-
final: true
|
|
2094
|
-
});
|
|
2467
|
+
await failTask(
|
|
2468
|
+
createTask(inputFiles),
|
|
2469
|
+
new Error("Agent did not complete governed task lifecycle")
|
|
2470
|
+
);
|
|
2095
2471
|
} catch (err) {
|
|
2096
|
-
|
|
2472
|
+
await failTask(createTask(inputFiles), err);
|
|
2097
2473
|
}
|
|
2098
2474
|
} finally {
|
|
2099
2475
|
active.delete(execution);
|
|
@@ -2140,7 +2516,7 @@ ${formatFileRefsSection(inputFiles)}` : text;
|
|
|
2140
2516
|
const threadId = task ? asString2(task.metadata?.threadId) : void 0;
|
|
2141
2517
|
if (threadId) {
|
|
2142
2518
|
try {
|
|
2143
|
-
const agent =
|
|
2519
|
+
const agent = import_core75.agentInstanceManager.getAgent(this.agentParams(threadId));
|
|
2144
2520
|
await agent.abort();
|
|
2145
2521
|
} catch (err) {
|
|
2146
2522
|
console.warn({
|
|
@@ -2151,6 +2527,26 @@ ${formatFileRefsSection(inputFiles)}` : text;
|
|
|
2151
2527
|
});
|
|
2152
2528
|
}
|
|
2153
2529
|
}
|
|
2530
|
+
if (this.taskStore) {
|
|
2531
|
+
const canceledTask = {
|
|
2532
|
+
...task ?? {
|
|
2533
|
+
kind: "task",
|
|
2534
|
+
id: taskId,
|
|
2535
|
+
contextId: "",
|
|
2536
|
+
status: { state: "canceled" }
|
|
2537
|
+
},
|
|
2538
|
+
status: { state: "canceled", timestamp: isoNow() }
|
|
2539
|
+
};
|
|
2540
|
+
try {
|
|
2541
|
+
await this.taskStore.save(canceledTask);
|
|
2542
|
+
} catch (saveError) {
|
|
2543
|
+
console.warn({
|
|
2544
|
+
event: "a2a:settle:save_failed",
|
|
2545
|
+
taskId,
|
|
2546
|
+
error: saveError instanceof Error ? saveError.message : String(saveError)
|
|
2547
|
+
});
|
|
2548
|
+
}
|
|
2549
|
+
}
|
|
2154
2550
|
bus.publish({
|
|
2155
2551
|
kind: "status-update",
|
|
2156
2552
|
taskId,
|
|
@@ -2494,10 +2890,10 @@ function isAsyncGenerator(value) {
|
|
|
2494
2890
|
}
|
|
2495
2891
|
function registerA2AStandardRoutes(app2, deps) {
|
|
2496
2892
|
const authService = deps.authService;
|
|
2497
|
-
const resolveTasks = deps.getTaskStoreLattice ?? (() => (0,
|
|
2498
|
-
const resolveTaskWorkItems = deps.getTaskWorkItemStore ?? (() => (0,
|
|
2499
|
-
const getAssistantStore2 = deps.getAssistantStore ?? (() => (0,
|
|
2500
|
-
const getProjectStore2 = deps.getProjectStore ?? (() => (0,
|
|
2893
|
+
const resolveTasks = deps.getTaskStoreLattice ?? (() => (0, import_core76.getStoreLattice)("default", "task").store);
|
|
2894
|
+
const resolveTaskWorkItems = deps.getTaskWorkItemStore ?? (() => (0, import_core76.getStoreLattice)("default", "taskWorkItem").store);
|
|
2895
|
+
const getAssistantStore2 = deps.getAssistantStore ?? (() => (0, import_core76.getStoreLattice)("default", "assistant").store);
|
|
2896
|
+
const getProjectStore2 = deps.getProjectStore ?? (() => (0, import_core76.getStoreLattice)("default", "project").store);
|
|
2501
2897
|
const runtimeRegistry = deps.runtimeRegistry ?? new A2ARuntimeRegistry();
|
|
2502
2898
|
app2.addHook("onClose", async () => {
|
|
2503
2899
|
runtimeRegistry.close();
|
|
@@ -2580,7 +2976,7 @@ function registerA2AStandardRoutes(app2, deps) {
|
|
|
2580
2976
|
const taskStore = assistantHasGovernedTask(assistant) ? new A2ATaskStoreAdapter({
|
|
2581
2977
|
taskStore: internalTasks,
|
|
2582
2978
|
workItemStore: workItems,
|
|
2583
|
-
lifecycle: (0,
|
|
2979
|
+
lifecycle: (0, import_core76.createTaskLifecycleService)({
|
|
2584
2980
|
taskStore: internalTasks,
|
|
2585
2981
|
workItemStore: workItems
|
|
2586
2982
|
}),
|
|
@@ -2699,7 +3095,7 @@ data: ${JSON.stringify(errorResponse)}
|
|
|
2699
3095
|
const taskStore = assistantHasGovernedTask(assistant) ? new A2ATaskStoreAdapter({
|
|
2700
3096
|
taskStore: internalTasks,
|
|
2701
3097
|
workItemStore: workItems,
|
|
2702
|
-
lifecycle: (0,
|
|
3098
|
+
lifecycle: (0, import_core76.createTaskLifecycleService)({
|
|
2703
3099
|
taskStore: internalTasks,
|
|
2704
3100
|
workItemStore: workItems
|
|
2705
3101
|
}),
|
|
@@ -2731,6 +3127,16 @@ data: ${JSON.stringify(data)}
|
|
|
2731
3127
|
await executor.execute(requestContext, bus);
|
|
2732
3128
|
} catch (err) {
|
|
2733
3129
|
request.log.error({ err }, "a2a:test-call:execution");
|
|
3130
|
+
try {
|
|
3131
|
+
await taskStore.save({
|
|
3132
|
+
kind: "task",
|
|
3133
|
+
id: taskId,
|
|
3134
|
+
contextId,
|
|
3135
|
+
status: { state: "failed", timestamp: (/* @__PURE__ */ new Date()).toISOString() }
|
|
3136
|
+
});
|
|
3137
|
+
} catch (saveError) {
|
|
3138
|
+
request.log.error({ err: saveError }, "a2a:test-call:settle");
|
|
3139
|
+
}
|
|
2734
3140
|
sendEvent("status-update", {
|
|
2735
3141
|
kind: "status-update",
|
|
2736
3142
|
taskId,
|
|
@@ -2744,13 +3150,13 @@ data: ${JSON.stringify(data)}
|
|
|
2744
3150
|
}
|
|
2745
3151
|
);
|
|
2746
3152
|
}
|
|
2747
|
-
var import_uuid12, import_server2,
|
|
3153
|
+
var import_uuid12, import_server2, import_core76, SSE_HEADERS;
|
|
2748
3154
|
var init_a2a_standard = __esm({
|
|
2749
3155
|
"src/routes/a2a-standard.ts"() {
|
|
2750
3156
|
"use strict";
|
|
2751
3157
|
import_uuid12 = require("uuid");
|
|
2752
3158
|
import_server2 = require("@a2a-js/sdk/server");
|
|
2753
|
-
|
|
3159
|
+
import_core76 = require("@axiom-lattice/core");
|
|
2754
3160
|
init_A2AAuthService();
|
|
2755
3161
|
init_A2AAgentCardBuilder();
|
|
2756
3162
|
init_A2ATaskStoreAdapter();
|
|
@@ -2958,11 +3364,11 @@ var init_a2a = __esm({
|
|
|
2958
3364
|
});
|
|
2959
3365
|
|
|
2960
3366
|
// src/services/open/openAuthService.ts
|
|
2961
|
-
var
|
|
3367
|
+
var import_protocols36, OpenAuthService;
|
|
2962
3368
|
var init_openAuthService = __esm({
|
|
2963
3369
|
"src/services/open/openAuthService.ts"() {
|
|
2964
3370
|
"use strict";
|
|
2965
|
-
|
|
3371
|
+
import_protocols36 = require("@axiom-lattice/protocols");
|
|
2966
3372
|
OpenAuthService = class {
|
|
2967
3373
|
constructor(keyStore) {
|
|
2968
3374
|
this.keyStore = keyStore;
|
|
@@ -2976,7 +3382,7 @@ var init_openAuthService = __esm({
|
|
|
2976
3382
|
kind: "api_key",
|
|
2977
3383
|
tenantId: record.tenantId,
|
|
2978
3384
|
projectId: record.projectId,
|
|
2979
|
-
grants: (0,
|
|
3385
|
+
grants: (0, import_protocols36.effectiveGrants)(record)
|
|
2980
3386
|
};
|
|
2981
3387
|
}
|
|
2982
3388
|
};
|
|
@@ -2984,11 +3390,11 @@ var init_openAuthService = __esm({
|
|
|
2984
3390
|
});
|
|
2985
3391
|
|
|
2986
3392
|
// src/services/open/openCredentialService.ts
|
|
2987
|
-
var
|
|
3393
|
+
var import_protocols37, OpenCredentialService;
|
|
2988
3394
|
var init_openCredentialService = __esm({
|
|
2989
3395
|
"src/services/open/openCredentialService.ts"() {
|
|
2990
3396
|
"use strict";
|
|
2991
|
-
|
|
3397
|
+
import_protocols37 = require("@axiom-lattice/protocols");
|
|
2992
3398
|
init_openToken();
|
|
2993
3399
|
init_openAuthService();
|
|
2994
3400
|
OpenCredentialService = class {
|
|
@@ -3008,6 +3414,7 @@ var init_openCredentialService = __esm({
|
|
|
3008
3414
|
projectId: token.projectId,
|
|
3009
3415
|
workspaceId: token.workspaceId,
|
|
3010
3416
|
sandboxName: token.sandboxName,
|
|
3417
|
+
depth: token.depth,
|
|
3011
3418
|
grants: token.grants
|
|
3012
3419
|
};
|
|
3013
3420
|
}
|
|
@@ -3501,8 +3908,8 @@ function exposedDeclarations(plugin) {
|
|
|
3501
3908
|
return (plugin.meta.tools ?? []).filter((t2) => t2.expose);
|
|
3502
3909
|
}
|
|
3503
3910
|
async function registerExposedPluginTools() {
|
|
3504
|
-
for (const key of
|
|
3505
|
-
const plugin =
|
|
3911
|
+
for (const key of import_core77.PluginRegistry.list()) {
|
|
3912
|
+
const plugin = import_core77.PluginRegistry.get(key);
|
|
3506
3913
|
if (!plugin?.middleware) continue;
|
|
3507
3914
|
const exposed = exposedDeclarations(plugin);
|
|
3508
3915
|
if (exposed.length === 0) continue;
|
|
@@ -3537,8 +3944,8 @@ async function registerExposedPluginTools() {
|
|
|
3537
3944
|
}
|
|
3538
3945
|
function collectExposedPluginUiResources(grants) {
|
|
3539
3946
|
const resources = /* @__PURE__ */ new Map();
|
|
3540
|
-
for (const type of
|
|
3541
|
-
const plugin =
|
|
3947
|
+
for (const type of import_core77.PluginRegistry.list()) {
|
|
3948
|
+
const plugin = import_core77.PluginRegistry.get(type);
|
|
3542
3949
|
if (!plugin?.middleware) continue;
|
|
3543
3950
|
const exposedNames = new Set(exposedDeclarations(plugin).map((d) => d.name));
|
|
3544
3951
|
if (exposedNames.size === 0) continue;
|
|
@@ -3562,11 +3969,11 @@ function collectExposedPluginUiResources(grants) {
|
|
|
3562
3969
|
}
|
|
3563
3970
|
return resources;
|
|
3564
3971
|
}
|
|
3565
|
-
var
|
|
3972
|
+
var import_core77;
|
|
3566
3973
|
var init_registerExposedPlugins = __esm({
|
|
3567
3974
|
"src/services/open/registerExposedPlugins.ts"() {
|
|
3568
3975
|
"use strict";
|
|
3569
|
-
|
|
3976
|
+
import_core77 = require("@axiom-lattice/core");
|
|
3570
3977
|
init_openLattice();
|
|
3571
3978
|
init_pluginExposeAdapter();
|
|
3572
3979
|
}
|
|
@@ -3581,14 +3988,14 @@ function toText(result) {
|
|
|
3581
3988
|
}
|
|
3582
3989
|
function defaultCatalog() {
|
|
3583
3990
|
return {
|
|
3584
|
-
getValidatedManifest: (tenantId, type) => (0,
|
|
3585
|
-
getExecutor: () => (0,
|
|
3586
|
-
readPluginFile: (tenantId, type, relPath) => (0,
|
|
3991
|
+
getValidatedManifest: (tenantId, type) => (0, import_core78.getSandboxPluginCatalog)().getValidatedManifest(tenantId, type),
|
|
3992
|
+
getExecutor: () => (0, import_core78.getSandboxPluginCatalog)().getExecutor(),
|
|
3993
|
+
readPluginFile: (tenantId, type, relPath) => (0, import_core78.getSandboxPluginCatalog)().readPluginFile(tenantId, type, relPath)
|
|
3587
3994
|
};
|
|
3588
3995
|
}
|
|
3589
3996
|
async function defaultResolveConnections(pluginType, ctx) {
|
|
3590
3997
|
try {
|
|
3591
|
-
return await (0,
|
|
3998
|
+
return await (0, import_core78.resolveSandboxPluginConnections)(
|
|
3592
3999
|
pluginType,
|
|
3593
4000
|
{ connectAll: true },
|
|
3594
4001
|
{
|
|
@@ -3617,7 +4024,7 @@ function mergeOpenCatalog(globalCatalog, tenantTools) {
|
|
|
3617
4024
|
async function buildTenantOpenPlugins(tenantId, grants, deps = {}) {
|
|
3618
4025
|
const catalog = deps.catalog ?? defaultCatalog();
|
|
3619
4026
|
const listPlugins = deps.listPlugins ?? (async (tenant2) => {
|
|
3620
|
-
const snapshot = await (0,
|
|
4027
|
+
const snapshot = await (0, import_core78.getSandboxPluginCatalog)().ensureLoaded(tenant2);
|
|
3621
4028
|
return { plugins: snapshot.plugins, diagnostics: snapshot.diagnostics };
|
|
3622
4029
|
});
|
|
3623
4030
|
const resolveConnections = deps.resolveConnections ?? defaultResolveConnections;
|
|
@@ -3659,7 +4066,7 @@ async function buildTenantOpenPlugins(tenantId, grants, deps = {}) {
|
|
|
3659
4066
|
domain,
|
|
3660
4067
|
action: tool.name,
|
|
3661
4068
|
description: tool.description,
|
|
3662
|
-
schema: (0,
|
|
4069
|
+
schema: (0, import_core78.jsonSchemaToZod)(tool.schema),
|
|
3663
4070
|
annotations: {
|
|
3664
4071
|
readOnlyHint: tool.readOnly ?? false,
|
|
3665
4072
|
destructiveHint: tool.destructive ?? false
|
|
@@ -3710,11 +4117,11 @@ async function buildTenantOpenPlugins(tenantId, grants, deps = {}) {
|
|
|
3710
4117
|
}
|
|
3711
4118
|
};
|
|
3712
4119
|
}
|
|
3713
|
-
var
|
|
4120
|
+
var import_core78;
|
|
3714
4121
|
var init_tenantOpenPlugins = __esm({
|
|
3715
4122
|
"src/services/open/tenantOpenPlugins.ts"() {
|
|
3716
4123
|
"use strict";
|
|
3717
|
-
|
|
4124
|
+
import_core78 = require("@axiom-lattice/core");
|
|
3718
4125
|
init_openLattice();
|
|
3719
4126
|
init_pluginToolExecution();
|
|
3720
4127
|
}
|
|
@@ -3751,13 +4158,13 @@ function emptyTenantPlugins() {
|
|
|
3751
4158
|
}
|
|
3752
4159
|
function registerOpenRoutes(app2, deps = {}) {
|
|
3753
4160
|
const openAuth = deps.openAuth ?? new OpenCredentialService(
|
|
3754
|
-
(0,
|
|
3755
|
-
(0,
|
|
4161
|
+
(0, import_core79.getStoreLattice)("default", "a2aApiKey").store,
|
|
4162
|
+
(0, import_core79.getStoreLattice)("default", "project").store
|
|
3756
4163
|
);
|
|
3757
4164
|
const grantsSource = deps.grantsSource ?? ((ctx) => ctx.grants);
|
|
3758
4165
|
const audit = deps.audit ?? (() => {
|
|
3759
4166
|
try {
|
|
3760
|
-
const store2 = (0,
|
|
4167
|
+
const store2 = (0, import_core79.getStoreLattice)("default", "openAudit").store;
|
|
3761
4168
|
return new OpenAuditService(store2);
|
|
3762
4169
|
} catch {
|
|
3763
4170
|
return void 0;
|
|
@@ -3843,7 +4250,8 @@ function registerOpenRoutes(app2, deps = {}) {
|
|
|
3843
4250
|
const isTenantRoute = tenant2.hasTool(toolName) && !globalToolNames.has(toolName);
|
|
3844
4251
|
const runConfig = {
|
|
3845
4252
|
sandboxName: context.sandboxName,
|
|
3846
|
-
credentialId: context.credentialId
|
|
4253
|
+
credentialId: context.credentialId,
|
|
4254
|
+
depth: context.depth
|
|
3847
4255
|
};
|
|
3848
4256
|
const result = isTenantRoute ? await tenant2.invoke(toolName, args, {
|
|
3849
4257
|
tenantId: context.tenantId,
|
|
@@ -3911,12 +4319,12 @@ function registerOpenRoutes(app2, deps = {}) {
|
|
|
3911
4319
|
}
|
|
3912
4320
|
);
|
|
3913
4321
|
}
|
|
3914
|
-
var import_types,
|
|
4322
|
+
var import_types, import_core79, RPC_ERROR;
|
|
3915
4323
|
var init_open = __esm({
|
|
3916
4324
|
"src/routes/open.ts"() {
|
|
3917
4325
|
"use strict";
|
|
3918
4326
|
import_types = require("@modelcontextprotocol/sdk/types.js");
|
|
3919
|
-
|
|
4327
|
+
import_core79 = require("@axiom-lattice/core");
|
|
3920
4328
|
init_openCredentialService();
|
|
3921
4329
|
init_openAuditService();
|
|
3922
4330
|
init_openRateLimiter();
|
|
@@ -3949,7 +4357,7 @@ function registerOpenSessionRoutes(app2) {
|
|
|
3949
4357
|
if (typeof shareToken !== "string" || shareToken.length === 0) {
|
|
3950
4358
|
return reply.status(400).send({ error: "SHARE_TOKEN_REQUIRED" });
|
|
3951
4359
|
}
|
|
3952
|
-
const store2 = (0,
|
|
4360
|
+
const store2 = (0, import_core80.getStoreLattice)("default", "sharedResource").store;
|
|
3953
4361
|
const record = await store2.findByToken(shareToken);
|
|
3954
4362
|
if (!record || record.revoked) {
|
|
3955
4363
|
return reply.status(404).send({ error: "SHARE_NOT_FOUND" });
|
|
@@ -3974,11 +4382,11 @@ function registerOpenSessionRoutes(app2) {
|
|
|
3974
4382
|
}
|
|
3975
4383
|
);
|
|
3976
4384
|
}
|
|
3977
|
-
var
|
|
4385
|
+
var import_core80;
|
|
3978
4386
|
var init_open_session = __esm({
|
|
3979
4387
|
"src/routes/open-session.ts"() {
|
|
3980
4388
|
"use strict";
|
|
3981
|
-
|
|
4389
|
+
import_core80 = require("@axiom-lattice/core");
|
|
3982
4390
|
init_openToken();
|
|
3983
4391
|
init_previewToken();
|
|
3984
4392
|
init_openLattice();
|
|
@@ -3987,13 +4395,13 @@ var init_open_session = __esm({
|
|
|
3987
4395
|
|
|
3988
4396
|
// src/services/open/openCatalogService.ts
|
|
3989
4397
|
async function defaultListTenantPlugins(tenantId) {
|
|
3990
|
-
return (await (0,
|
|
4398
|
+
return (await (0, import_core81.getSandboxPluginCatalog)().ensureLoaded(tenantId)).plugins;
|
|
3991
4399
|
}
|
|
3992
|
-
var
|
|
4400
|
+
var import_core81, OpenCatalogService;
|
|
3993
4401
|
var init_openCatalogService = __esm({
|
|
3994
4402
|
"src/services/open/openCatalogService.ts"() {
|
|
3995
4403
|
"use strict";
|
|
3996
|
-
|
|
4404
|
+
import_core81 = require("@axiom-lattice/core");
|
|
3997
4405
|
init_openLattice();
|
|
3998
4406
|
OpenCatalogService = class {
|
|
3999
4407
|
constructor(assistantStore, lattice = openLattice, listTenantPlugins2 = defaultListTenantPlugins) {
|
|
@@ -4068,17 +4476,17 @@ function registerOpenCatalogRoutes(app2) {
|
|
|
4068
4476
|
if (!tenantId) {
|
|
4069
4477
|
return reply.status(401).send({ success: false, error: "Unauthorized" });
|
|
4070
4478
|
}
|
|
4071
|
-
const assistantStore = (0,
|
|
4479
|
+
const assistantStore = (0, import_core82.getStoreLattice)("default", "assistant").store;
|
|
4072
4480
|
const service2 = new OpenCatalogService(assistantStore);
|
|
4073
4481
|
const catalog = await service2.buildForTenant(tenantId);
|
|
4074
4482
|
return reply.status(200).send({ success: true, data: catalog });
|
|
4075
4483
|
});
|
|
4076
4484
|
}
|
|
4077
|
-
var
|
|
4485
|
+
var import_core82;
|
|
4078
4486
|
var init_open_catalog = __esm({
|
|
4079
4487
|
"src/routes/open-catalog.ts"() {
|
|
4080
4488
|
"use strict";
|
|
4081
|
-
|
|
4489
|
+
import_core82 = require("@axiom-lattice/core");
|
|
4082
4490
|
init_openCatalogService();
|
|
4083
4491
|
}
|
|
4084
4492
|
});
|
|
@@ -4090,7 +4498,14 @@ __export(sandboxProvider_exports, {
|
|
|
4090
4498
|
resolveContextSandbox: () => resolveContextSandbox
|
|
4091
4499
|
});
|
|
4092
4500
|
async function resolveContextSandbox(ctx) {
|
|
4093
|
-
|
|
4501
|
+
const sandboxName = ctx.runConfig?.sandboxName;
|
|
4502
|
+
if (typeof sandboxName === "string" && sandboxName.length > 0) {
|
|
4503
|
+
try {
|
|
4504
|
+
return await import_core83.sandboxLatticeManager.getSandbox(sandboxName);
|
|
4505
|
+
} catch {
|
|
4506
|
+
}
|
|
4507
|
+
}
|
|
4508
|
+
return import_core83.sandboxLatticeManager.getSandboxFromConfig({
|
|
4094
4509
|
assistant_id: "",
|
|
4095
4510
|
thread_id: "",
|
|
4096
4511
|
tenantId: ctx.tenantId,
|
|
@@ -4188,12 +4603,12 @@ ${truncated}`
|
|
|
4188
4603
|
}
|
|
4189
4604
|
};
|
|
4190
4605
|
}
|
|
4191
|
-
var import_zod21,
|
|
4606
|
+
var import_zod21, import_core83, MAX_OUTPUT_BYTES;
|
|
4192
4607
|
var init_sandboxProvider = __esm({
|
|
4193
4608
|
"src/services/open/providers/sandboxProvider.ts"() {
|
|
4194
4609
|
"use strict";
|
|
4195
4610
|
import_zod21 = require("zod");
|
|
4196
|
-
|
|
4611
|
+
import_core83 = require("@axiom-lattice/core");
|
|
4197
4612
|
MAX_OUTPUT_BYTES = 64e3;
|
|
4198
4613
|
}
|
|
4199
4614
|
});
|
|
@@ -4215,12 +4630,12 @@ function safePath(raw) {
|
|
|
4215
4630
|
}
|
|
4216
4631
|
function registerOpenFilesRoutes(app2, deps = {}) {
|
|
4217
4632
|
const openAuth = deps.openAuth ?? new OpenCredentialService(
|
|
4218
|
-
(0,
|
|
4219
|
-
(0,
|
|
4633
|
+
(0, import_core84.getStoreLattice)("default", "a2aApiKey").store,
|
|
4634
|
+
(0, import_core84.getStoreLattice)("default", "project").store
|
|
4220
4635
|
);
|
|
4221
4636
|
const audit = deps.audit ?? (() => {
|
|
4222
4637
|
try {
|
|
4223
|
-
const store2 = (0,
|
|
4638
|
+
const store2 = (0, import_core84.getStoreLattice)("default", "openAudit").store;
|
|
4224
4639
|
return new OpenAuditService(store2);
|
|
4225
4640
|
} catch {
|
|
4226
4641
|
return void 0;
|
|
@@ -4330,11 +4745,11 @@ function registerOpenFilesRoutes(app2, deps = {}) {
|
|
|
4330
4745
|
}
|
|
4331
4746
|
});
|
|
4332
4747
|
}
|
|
4333
|
-
var
|
|
4748
|
+
var import_core84;
|
|
4334
4749
|
var init_open_files = __esm({
|
|
4335
4750
|
"src/routes/open-files.ts"() {
|
|
4336
4751
|
"use strict";
|
|
4337
|
-
|
|
4752
|
+
import_core84 = require("@axiom-lattice/core");
|
|
4338
4753
|
init_openCredentialService();
|
|
4339
4754
|
init_openLattice();
|
|
4340
4755
|
init_sandboxProvider();
|
|
@@ -4356,7 +4771,7 @@ function registerOpenAuditRoutes(app2) {
|
|
|
4356
4771
|
return reply.status(401).send({ success: false, error: "Unauthorized" });
|
|
4357
4772
|
}
|
|
4358
4773
|
const status = request.query.status === "ok" || request.query.status === "error" ? request.query.status : void 0;
|
|
4359
|
-
const store2 = (0,
|
|
4774
|
+
const store2 = (0, import_core85.getStoreLattice)("default", "openAudit").store;
|
|
4360
4775
|
const records = await store2.query({
|
|
4361
4776
|
tenantId,
|
|
4362
4777
|
credentialId: request.query.credentialId,
|
|
@@ -4371,11 +4786,11 @@ function registerOpenAuditRoutes(app2) {
|
|
|
4371
4786
|
}
|
|
4372
4787
|
);
|
|
4373
4788
|
}
|
|
4374
|
-
var
|
|
4789
|
+
var import_core85;
|
|
4375
4790
|
var init_open_audit = __esm({
|
|
4376
4791
|
"src/routes/open-audit.ts"() {
|
|
4377
4792
|
"use strict";
|
|
4378
|
-
|
|
4793
|
+
import_core85 = require("@axiom-lattice/core");
|
|
4379
4794
|
}
|
|
4380
4795
|
});
|
|
4381
4796
|
|
|
@@ -4392,12 +4807,12 @@ function registerOpenExposureRoutes(app2, deps = {}) {
|
|
|
4392
4807
|
if (!tenantId) {
|
|
4393
4808
|
return reply.status(401).send({ success: false, error: "Unauthorized" });
|
|
4394
4809
|
}
|
|
4395
|
-
const keyStore = (0,
|
|
4810
|
+
const keyStore = (0, import_core86.getStoreLattice)("default", "a2aApiKey").store;
|
|
4396
4811
|
const record = await keyStore.findById(request.params.id);
|
|
4397
4812
|
if (!record || record.tenantId !== tenantId) {
|
|
4398
4813
|
return reply.status(404).send({ success: false, error: "Key not found" });
|
|
4399
4814
|
}
|
|
4400
|
-
const grants = (0,
|
|
4815
|
+
const grants = (0, import_protocols38.effectiveGrants)(record);
|
|
4401
4816
|
const forwardedHost = request.headers["x-forwarded-host"];
|
|
4402
4817
|
const host = (Array.isArray(forwardedHost) ? forwardedHost[0] : forwardedHost) ?? (Array.isArray(request.headers.host) ? request.headers.host[0] : request.headers.host) ?? request.hostname;
|
|
4403
4818
|
const baseUrl = `${request.protocol}://${host}`;
|
|
@@ -4426,7 +4841,7 @@ function registerOpenExposureRoutes(app2, deps = {}) {
|
|
|
4426
4841
|
hasUi: Boolean(t2.ui)
|
|
4427
4842
|
}));
|
|
4428
4843
|
const agentGrant = grants.find((g) => g.domain === "agent");
|
|
4429
|
-
const assistantStore = (0,
|
|
4844
|
+
const assistantStore = (0, import_core86.getStoreLattice)("default", "assistant").store;
|
|
4430
4845
|
const agents = [];
|
|
4431
4846
|
for (const assistantId of agentGrant?.items ?? []) {
|
|
4432
4847
|
const assistant = await assistantStore.getAssistantById(
|
|
@@ -4461,12 +4876,12 @@ function registerOpenExposureRoutes(app2, deps = {}) {
|
|
|
4461
4876
|
}
|
|
4462
4877
|
);
|
|
4463
4878
|
}
|
|
4464
|
-
var
|
|
4879
|
+
var import_core86, import_protocols38;
|
|
4465
4880
|
var init_open_exposure = __esm({
|
|
4466
4881
|
"src/routes/open-exposure.ts"() {
|
|
4467
4882
|
"use strict";
|
|
4468
|
-
|
|
4469
|
-
|
|
4883
|
+
import_core86 = require("@axiom-lattice/core");
|
|
4884
|
+
import_protocols38 = require("@axiom-lattice/protocols");
|
|
4470
4885
|
init_openLattice();
|
|
4471
4886
|
init_tenantOpenPlugins();
|
|
4472
4887
|
init_A2AAgentCardBuilder();
|
|
@@ -4585,7 +5000,7 @@ function createAgentProvider(deps = {}) {
|
|
|
4585
5000
|
} catch {
|
|
4586
5001
|
}
|
|
4587
5002
|
}
|
|
4588
|
-
const agent =
|
|
5003
|
+
const agent = import_core87.agentInstanceManager.getAgent({
|
|
4589
5004
|
tenant_id: ctx.tenantId,
|
|
4590
5005
|
assistant_id: assistantId,
|
|
4591
5006
|
thread_id: threadId,
|
|
@@ -4599,8 +5014,8 @@ function createAgentProvider(deps = {}) {
|
|
|
4599
5014
|
const stream = agent.chunkStream(messageId, [...STOP_TYPES]);
|
|
4600
5015
|
for await (const chunk of stream) {
|
|
4601
5016
|
const text = chunk.data?.content;
|
|
4602
|
-
if (chunk.type ===
|
|
4603
|
-
if (chunk.type ===
|
|
5017
|
+
if (chunk.type === import_protocols39.MessageChunkTypes.INTERRUPT) break;
|
|
5018
|
+
if (chunk.type === import_protocols39.MessageChunkTypes.AI && text) {
|
|
4604
5019
|
parts.push(text);
|
|
4605
5020
|
}
|
|
4606
5021
|
}
|
|
@@ -4610,14 +5025,289 @@ function createAgentProvider(deps = {}) {
|
|
|
4610
5025
|
}
|
|
4611
5026
|
};
|
|
4612
5027
|
}
|
|
4613
|
-
var import_zod23,
|
|
5028
|
+
var import_zod23, import_core87, import_protocols39, STOP_TYPES;
|
|
4614
5029
|
var init_agentProvider = __esm({
|
|
4615
5030
|
"src/services/open/providers/agentProvider.ts"() {
|
|
4616
5031
|
"use strict";
|
|
4617
5032
|
import_zod23 = require("zod");
|
|
4618
|
-
|
|
4619
|
-
|
|
4620
|
-
STOP_TYPES = [
|
|
5033
|
+
import_core87 = require("@axiom-lattice/core");
|
|
5034
|
+
import_protocols39 = require("@axiom-lattice/protocols");
|
|
5035
|
+
STOP_TYPES = [import_protocols39.MessageChunkTypes.MESSAGE_COMPLETED];
|
|
5036
|
+
}
|
|
5037
|
+
});
|
|
5038
|
+
|
|
5039
|
+
// src/services/open/sandboxOpenReflection.ts
|
|
5040
|
+
function cloneGrants(grants) {
|
|
5041
|
+
return grants.map((grant) => ({
|
|
5042
|
+
...grant,
|
|
5043
|
+
items: grant.items ? [...grant.items] : void 0
|
|
5044
|
+
}));
|
|
5045
|
+
}
|
|
5046
|
+
function normalizeOpenExpose(value) {
|
|
5047
|
+
if (!Array.isArray(value)) return [];
|
|
5048
|
+
const out = [];
|
|
5049
|
+
for (const entry of value) {
|
|
5050
|
+
if (typeof entry === "string") {
|
|
5051
|
+
if (entry) out.push(entry);
|
|
5052
|
+
} else if (entry && typeof entry === "object") {
|
|
5053
|
+
const name = entry.name;
|
|
5054
|
+
if (typeof name === "string" && name) out.push(name);
|
|
5055
|
+
}
|
|
5056
|
+
}
|
|
5057
|
+
return out;
|
|
5058
|
+
}
|
|
5059
|
+
function extractMiddleware(container) {
|
|
5060
|
+
if (!container || typeof container !== "object") return void 0;
|
|
5061
|
+
const raw = container.middleware;
|
|
5062
|
+
if (!Array.isArray(raw)) return void 0;
|
|
5063
|
+
const out = [];
|
|
5064
|
+
for (const entry of raw) {
|
|
5065
|
+
if (!entry || typeof entry !== "object") continue;
|
|
5066
|
+
const type = entry.type;
|
|
5067
|
+
if (typeof type !== "string" || type.length === 0) continue;
|
|
5068
|
+
const enabled = entry.enabled;
|
|
5069
|
+
const rawAllowed = entry.allowedTools;
|
|
5070
|
+
const allowedTools = Array.isArray(rawAllowed) ? rawAllowed.filter((t2) => typeof t2 === "string" && t2.length > 0) : void 0;
|
|
5071
|
+
out.push({ type, enabled: typeof enabled === "boolean" ? enabled : void 0, allowedTools });
|
|
5072
|
+
}
|
|
5073
|
+
return out;
|
|
5074
|
+
}
|
|
5075
|
+
function extractSubAgents(config) {
|
|
5076
|
+
if (!config || typeof config !== "object") return void 0;
|
|
5077
|
+
const raw = config.subAgents;
|
|
5078
|
+
if (!Array.isArray(raw)) return void 0;
|
|
5079
|
+
const out = raw.filter((id3) => typeof id3 === "string" && id3.length > 0);
|
|
5080
|
+
return out.length > 0 ? out : void 0;
|
|
5081
|
+
}
|
|
5082
|
+
async function computeGrants(tenantId, assistantId, deps) {
|
|
5083
|
+
await deps.ensure?.(tenantId);
|
|
5084
|
+
let context = await deps.getAgentConfig?.(tenantId, assistantId);
|
|
5085
|
+
if (context === void 0) {
|
|
5086
|
+
const middleware = await deps.getAssistantMiddleware?.(tenantId, assistantId);
|
|
5087
|
+
if (middleware === void 0) return [];
|
|
5088
|
+
context = { middleware };
|
|
5089
|
+
}
|
|
5090
|
+
const byDomain = /* @__PURE__ */ new Map();
|
|
5091
|
+
const add = (domain, items) => {
|
|
5092
|
+
let bucket = byDomain.get(domain);
|
|
5093
|
+
if (!bucket) {
|
|
5094
|
+
bucket = /* @__PURE__ */ new Set();
|
|
5095
|
+
byDomain.set(domain, bucket);
|
|
5096
|
+
}
|
|
5097
|
+
for (const item of items) bucket.add(item);
|
|
5098
|
+
};
|
|
5099
|
+
for (const entry of context.middleware ?? []) {
|
|
5100
|
+
if (!entry || entry.enabled === false) continue;
|
|
5101
|
+
if (typeof entry.type !== "string" || entry.type.length === 0) continue;
|
|
5102
|
+
let actions = deps.exposedActionsByType(entry.type);
|
|
5103
|
+
if (actions.length === 0) continue;
|
|
5104
|
+
const allowedTools = entry.allowedTools;
|
|
5105
|
+
if (Array.isArray(allowedTools) && allowedTools.length > 0) {
|
|
5106
|
+
const allowed = new Set(allowedTools);
|
|
5107
|
+
actions = actions.filter((action) => allowed.has(action));
|
|
5108
|
+
if (actions.length === 0) continue;
|
|
5109
|
+
}
|
|
5110
|
+
add(entry.type, actions);
|
|
5111
|
+
}
|
|
5112
|
+
const subAgents = context.subAgents ?? [];
|
|
5113
|
+
if (subAgents.length > 0 && deps.resolvableAssistants) {
|
|
5114
|
+
const resolvable = await deps.resolvableAssistants(tenantId);
|
|
5115
|
+
const kept = subAgents.filter(
|
|
5116
|
+
(id3) => typeof id3 === "string" && id3.length > 0 && resolvable.has(id3)
|
|
5117
|
+
);
|
|
5118
|
+
if (kept.length > 0) add("agent", kept);
|
|
5119
|
+
}
|
|
5120
|
+
return [...byDomain].map(([domain, items]) => ({ domain, items: [...items] }));
|
|
5121
|
+
}
|
|
5122
|
+
async function resolveAgentOpenGrants(tenantId, assistantId, deps) {
|
|
5123
|
+
try {
|
|
5124
|
+
const key = `${tenantId}:${assistantId}`;
|
|
5125
|
+
const now = deps.now ? deps.now() : Date.now();
|
|
5126
|
+
const hit = cache.get(key);
|
|
5127
|
+
if (hit && hit.expiresAt > now) return cloneGrants(hit.grants);
|
|
5128
|
+
const grants = await computeGrants(tenantId, assistantId, deps);
|
|
5129
|
+
cache.set(key, { grants, expiresAt: now + AGENT_REFLECTION_CACHE_TTL_MS });
|
|
5130
|
+
return cloneGrants(grants);
|
|
5131
|
+
} catch {
|
|
5132
|
+
return [];
|
|
5133
|
+
}
|
|
5134
|
+
}
|
|
5135
|
+
function createDefaultAgentReflectionDeps(tenantId) {
|
|
5136
|
+
(0, import_core88.ensureBuiltinAgentsForTenant)(tenantId);
|
|
5137
|
+
return {
|
|
5138
|
+
ensure: (t2) => import_core88.agentLatticeManager.initializeStoredAssistantsForTenant(t2),
|
|
5139
|
+
getAgentConfig: (t2, assistantId) => {
|
|
5140
|
+
const config = import_core88.agentLatticeManager.getAgentConfigWithTenant(t2, assistantId);
|
|
5141
|
+
if (!config) return void 0;
|
|
5142
|
+
return {
|
|
5143
|
+
middleware: extractMiddleware(config),
|
|
5144
|
+
subAgents: extractSubAgents(config)
|
|
5145
|
+
};
|
|
5146
|
+
},
|
|
5147
|
+
getAssistantMiddleware: async (t2, assistantId) => {
|
|
5148
|
+
const store2 = (0, import_core88.getStoreLattice)("default", "assistant").store;
|
|
5149
|
+
const assistant = await store2.getAssistantById(t2, assistantId);
|
|
5150
|
+
return extractMiddleware(assistant?.graphDefinition);
|
|
5151
|
+
},
|
|
5152
|
+
exposedActionsByType: (type) => {
|
|
5153
|
+
const plugin = import_core88.PluginRegistry.get(type);
|
|
5154
|
+
return plugin ? normalizeOpenExpose(plugin.meta.openExpose) : [];
|
|
5155
|
+
},
|
|
5156
|
+
resolvableAssistants: async (t2) => new Set(
|
|
5157
|
+
import_core88.agentLatticeManager.getAllAgentLatticesByTenant(t2).map((lattice) => lattice.config.key)
|
|
5158
|
+
)
|
|
5159
|
+
};
|
|
5160
|
+
}
|
|
5161
|
+
function mergeGrantsByDomain(grants) {
|
|
5162
|
+
const order = [];
|
|
5163
|
+
const items = /* @__PURE__ */ new Map();
|
|
5164
|
+
const unrestricted = /* @__PURE__ */ new Set();
|
|
5165
|
+
for (const grant of grants) {
|
|
5166
|
+
if (!grant || typeof grant.domain !== "string" || grant.domain.length === 0) continue;
|
|
5167
|
+
if (!items.has(grant.domain)) {
|
|
5168
|
+
items.set(grant.domain, /* @__PURE__ */ new Set());
|
|
5169
|
+
order.push(grant.domain);
|
|
5170
|
+
}
|
|
5171
|
+
if (!grant.items || grant.items.length === 0) {
|
|
5172
|
+
unrestricted.add(grant.domain);
|
|
5173
|
+
continue;
|
|
5174
|
+
}
|
|
5175
|
+
const bucket = items.get(grant.domain);
|
|
5176
|
+
if (!bucket) continue;
|
|
5177
|
+
for (const item of grant.items) {
|
|
5178
|
+
if (typeof item === "string" && item.length > 0) bucket.add(item);
|
|
5179
|
+
}
|
|
5180
|
+
}
|
|
5181
|
+
return order.map((domain) => {
|
|
5182
|
+
if (unrestricted.has(domain)) return { domain };
|
|
5183
|
+
return { domain, items: [...items.get(domain) ?? []] };
|
|
5184
|
+
});
|
|
5185
|
+
}
|
|
5186
|
+
async function computePluginGrants(tenantId, deps) {
|
|
5187
|
+
const grants = [...deps.globalExposedDomains?.() ?? []];
|
|
5188
|
+
if (deps.tenantExposedDomains) {
|
|
5189
|
+
grants.push(...await deps.tenantExposedDomains(tenantId));
|
|
5190
|
+
}
|
|
5191
|
+
if (deps.resolvableAssistants) {
|
|
5192
|
+
const resolvable = await deps.resolvableAssistants(tenantId);
|
|
5193
|
+
if (resolvable.size > 0) {
|
|
5194
|
+
grants.push({ domain: "agent", items: [...resolvable] });
|
|
5195
|
+
}
|
|
5196
|
+
}
|
|
5197
|
+
return mergeGrantsByDomain(grants);
|
|
5198
|
+
}
|
|
5199
|
+
async function resolvePluginOpenGrants(tenantId, deps) {
|
|
5200
|
+
try {
|
|
5201
|
+
const now = deps.now ? deps.now() : Date.now();
|
|
5202
|
+
const hit = pluginCache.get(tenantId);
|
|
5203
|
+
if (hit && hit.expiresAt > now) return cloneGrants(hit.grants);
|
|
5204
|
+
await deps.ensure?.(tenantId);
|
|
5205
|
+
const grants = await computePluginGrants(tenantId, deps);
|
|
5206
|
+
pluginCache.set(tenantId, { grants, expiresAt: now + PLUGIN_REFLECTION_CACHE_TTL_MS });
|
|
5207
|
+
return cloneGrants(grants);
|
|
5208
|
+
} catch {
|
|
5209
|
+
return [];
|
|
5210
|
+
}
|
|
5211
|
+
}
|
|
5212
|
+
function buildTenantExposedGrants(manifests) {
|
|
5213
|
+
const grants = [];
|
|
5214
|
+
for (const manifest of manifests) {
|
|
5215
|
+
const items = (manifest.tools ?? []).filter((tool) => tool.expose === true).map((tool) => tool.name);
|
|
5216
|
+
if (items.length > 0) grants.push({ domain: manifest.type, items });
|
|
5217
|
+
}
|
|
5218
|
+
return grants;
|
|
5219
|
+
}
|
|
5220
|
+
function createDefaultPluginReflectionDeps() {
|
|
5221
|
+
return {
|
|
5222
|
+
ensure: (tenantId) => import_core88.agentLatticeManager.initializeStoredAssistantsForTenant(tenantId),
|
|
5223
|
+
globalExposedDomains: () => {
|
|
5224
|
+
const grants = [];
|
|
5225
|
+
for (const type of import_core88.PluginRegistry.list()) {
|
|
5226
|
+
const plugin = import_core88.PluginRegistry.get(type);
|
|
5227
|
+
const items = normalizeOpenExpose(plugin?.meta.openExpose);
|
|
5228
|
+
if (items.length > 0) grants.push({ domain: type, items });
|
|
5229
|
+
}
|
|
5230
|
+
return grants;
|
|
5231
|
+
},
|
|
5232
|
+
tenantExposedDomains: async (tenantId) => {
|
|
5233
|
+
const { manifests } = await (0, import_core88.getSandboxPluginCatalog)().ensureLoaded(tenantId);
|
|
5234
|
+
return buildTenantExposedGrants(Object.values(manifests));
|
|
5235
|
+
},
|
|
5236
|
+
resolvableAssistants: async (tenantId) => new Set(
|
|
5237
|
+
import_core88.agentLatticeManager.getAllAgentLatticesByTenant(tenantId).map((lattice) => lattice.config.key)
|
|
5238
|
+
)
|
|
5239
|
+
};
|
|
5240
|
+
}
|
|
5241
|
+
var import_core88, AGENT_REFLECTION_CACHE_TTL_MS, cache, PLUGIN_REFLECTION_CACHE_TTL_MS, pluginCache;
|
|
5242
|
+
var init_sandboxOpenReflection = __esm({
|
|
5243
|
+
"src/services/open/sandboxOpenReflection.ts"() {
|
|
5244
|
+
"use strict";
|
|
5245
|
+
import_core88 = require("@axiom-lattice/core");
|
|
5246
|
+
AGENT_REFLECTION_CACHE_TTL_MS = 6e4;
|
|
5247
|
+
cache = /* @__PURE__ */ new Map();
|
|
5248
|
+
PLUGIN_REFLECTION_CACHE_TTL_MS = 6e4;
|
|
5249
|
+
pluginCache = /* @__PURE__ */ new Map();
|
|
5250
|
+
}
|
|
5251
|
+
});
|
|
5252
|
+
|
|
5253
|
+
// src/services/open/sandboxOpenCredentialProvider.ts
|
|
5254
|
+
var sandboxOpenCredentialProvider_exports = {};
|
|
5255
|
+
__export(sandboxOpenCredentialProvider_exports, {
|
|
5256
|
+
DEFAULT_SANDBOX_OPEN_GRANTS: () => DEFAULT_SANDBOX_OPEN_GRANTS,
|
|
5257
|
+
MAX_SANDBOX_OPEN_DEPTH: () => MAX_SANDBOX_OPEN_DEPTH,
|
|
5258
|
+
createSandboxOpenCredentialProvider: () => createSandboxOpenCredentialProvider,
|
|
5259
|
+
registerGatewaySandboxOpenCredentialProvider: () => registerGatewaySandboxOpenCredentialProvider
|
|
5260
|
+
});
|
|
5261
|
+
function defaultReflection() {
|
|
5262
|
+
return {
|
|
5263
|
+
agent: (tenantId, assistantId) => resolveAgentOpenGrants(tenantId, assistantId, createDefaultAgentReflectionDeps(tenantId)),
|
|
5264
|
+
plugin: (tenantId) => resolvePluginOpenGrants(tenantId, createDefaultPluginReflectionDeps())
|
|
5265
|
+
};
|
|
5266
|
+
}
|
|
5267
|
+
function createSandboxOpenCredentialProvider(options) {
|
|
5268
|
+
const reflection = options.reflection ?? defaultReflection();
|
|
5269
|
+
return async (context) => {
|
|
5270
|
+
if (!options.gatewayUrl) return void 0;
|
|
5271
|
+
const depth = (context.depth ?? 0) + 1;
|
|
5272
|
+
if (depth > MAX_SANDBOX_OPEN_DEPTH) {
|
|
5273
|
+
options.onError?.(new Error("sandbox open credential depth exceeded"));
|
|
5274
|
+
return void 0;
|
|
5275
|
+
}
|
|
5276
|
+
const reflected = context.assistantId ? await reflection.agent(context.tenantId, context.assistantId) : await reflection.plugin(context.tenantId);
|
|
5277
|
+
const grants = mergeGrantsByDomain([...DEFAULT_SANDBOX_OPEN_GRANTS, ...reflected]);
|
|
5278
|
+
const token = signOpenToken({
|
|
5279
|
+
kind: "sandbox_token",
|
|
5280
|
+
tenantId: context.tenantId,
|
|
5281
|
+
workspaceId: context.workspaceId ?? "",
|
|
5282
|
+
projectId: context.projectId ?? "",
|
|
5283
|
+
sandboxName: context.sandboxName,
|
|
5284
|
+
grants,
|
|
5285
|
+
depth
|
|
5286
|
+
});
|
|
5287
|
+
return { gatewayUrl: options.gatewayUrl, token };
|
|
5288
|
+
};
|
|
5289
|
+
}
|
|
5290
|
+
function registerGatewaySandboxOpenCredentialProvider(onError) {
|
|
5291
|
+
return (0, import_core89.registerSandboxOpenCredentialProvider)(
|
|
5292
|
+
createSandboxOpenCredentialProvider({
|
|
5293
|
+
gatewayUrl: process.env.PUBLIC_GATEWAY_URL?.trim() || void 0,
|
|
5294
|
+
onError
|
|
5295
|
+
}),
|
|
5296
|
+
{ onError }
|
|
5297
|
+
);
|
|
5298
|
+
}
|
|
5299
|
+
var import_core89, DEFAULT_SANDBOX_OPEN_GRANTS, MAX_SANDBOX_OPEN_DEPTH;
|
|
5300
|
+
var init_sandboxOpenCredentialProvider = __esm({
|
|
5301
|
+
"src/services/open/sandboxOpenCredentialProvider.ts"() {
|
|
5302
|
+
"use strict";
|
|
5303
|
+
import_core89 = require("@axiom-lattice/core");
|
|
5304
|
+
init_openToken();
|
|
5305
|
+
init_sandboxOpenReflection();
|
|
5306
|
+
DEFAULT_SANDBOX_OPEN_GRANTS = [
|
|
5307
|
+
{ domain: "sandbox", items: ["files_read", "files_list", "files_write", "shell_exec"] },
|
|
5308
|
+
{ domain: "kb", items: ["search", "entries_read"] }
|
|
5309
|
+
];
|
|
5310
|
+
MAX_SANDBOX_OPEN_DEPTH = 5;
|
|
4621
5311
|
}
|
|
4622
5312
|
});
|
|
4623
5313
|
|
|
@@ -4647,12 +5337,12 @@ var resources_exports = {};
|
|
|
4647
5337
|
__export(resources_exports, {
|
|
4648
5338
|
ResourceController: () => ResourceController
|
|
4649
5339
|
});
|
|
4650
|
-
var import_bcryptjs,
|
|
5340
|
+
var import_bcryptjs, import_core90, ResourceController;
|
|
4651
5341
|
var init_resources = __esm({
|
|
4652
5342
|
"src/controllers/resources.ts"() {
|
|
4653
5343
|
"use strict";
|
|
4654
5344
|
import_bcryptjs = __toESM(require("bcryptjs"));
|
|
4655
|
-
|
|
5345
|
+
import_core90 = require("@axiom-lattice/core");
|
|
4656
5346
|
init_mime();
|
|
4657
5347
|
init_http_range();
|
|
4658
5348
|
init_sandboxGrants();
|
|
@@ -4669,14 +5359,14 @@ var init_resources = __esm({
|
|
|
4669
5359
|
if (!workspaceId || !projectId) {
|
|
4670
5360
|
return reply.status(400).send({ error: "x-workspace-id and x-project-id headers required" });
|
|
4671
5361
|
}
|
|
4672
|
-
const payload = (0,
|
|
5362
|
+
const payload = (0, import_core90.createSharePayload)(
|
|
4673
5363
|
tenantId,
|
|
4674
5364
|
workspaceId,
|
|
4675
5365
|
projectId,
|
|
4676
5366
|
userId,
|
|
4677
5367
|
body
|
|
4678
5368
|
);
|
|
4679
|
-
const token = (0,
|
|
5369
|
+
const token = (0, import_core90.generateToken)();
|
|
4680
5370
|
try {
|
|
4681
5371
|
await this.deps.store.create({ ...payload, token });
|
|
4682
5372
|
this.deps.logger.info(
|
|
@@ -4828,7 +5518,7 @@ var init_resources = __esm({
|
|
|
4828
5518
|
resourcePath: subPath
|
|
4829
5519
|
}, subPath, ext, request, reply);
|
|
4830
5520
|
}
|
|
4831
|
-
const volume = (0,
|
|
5521
|
+
const volume = (0, import_core90.buildNamedVolumeName)("p", "project", tenantId, workspaceId, projectId);
|
|
4832
5522
|
return this._resolveAndServe(
|
|
4833
5523
|
volume,
|
|
4834
5524
|
subPath,
|
|
@@ -5039,7 +5729,18 @@ var init_resources = __esm({
|
|
|
5039
5729
|
// src/index.ts
|
|
5040
5730
|
var index_exports = {};
|
|
5041
5731
|
__export(index_exports, {
|
|
5042
|
-
LatticeGateway: () => LatticeGateway
|
|
5732
|
+
LatticeGateway: () => LatticeGateway,
|
|
5733
|
+
ProjectRoomEventBroker: () => ProjectRoomEventBroker,
|
|
5734
|
+
ROOM_EVENT_TOPIC: () => ROOM_EVENT_TOPIC,
|
|
5735
|
+
createOrphanRecoveryRuntime: () => createOrphanRecoveryRuntime,
|
|
5736
|
+
createRecoveryCallerDeps: () => createRecoveryCallerDeps,
|
|
5737
|
+
createTaskRunLiveness: () => createTaskRunLiveness,
|
|
5738
|
+
ingestRoomEvent: () => ingestRoomEvent,
|
|
5739
|
+
publishRoomEvent: () => publishRoomEvent,
|
|
5740
|
+
recoverTask: () => recoverTask,
|
|
5741
|
+
recoverTopCaller: () => recoverTopCaller,
|
|
5742
|
+
resolveTopCaller: () => resolveTopCaller,
|
|
5743
|
+
runOrphanRecovery: () => runOrphanRecovery
|
|
5043
5744
|
});
|
|
5044
5745
|
module.exports = __toCommonJS(index_exports);
|
|
5045
5746
|
var import_config2 = require("dotenv/config");
|
|
@@ -5715,7 +6416,7 @@ var getAgentGraph = async (request, reply) => {
|
|
|
5715
6416
|
try {
|
|
5716
6417
|
const { assistantId } = request.params;
|
|
5717
6418
|
const tenant_id = getTenantId(request);
|
|
5718
|
-
const agent = import_core.agentInstanceManager.
|
|
6419
|
+
const agent = import_core.agentInstanceManager.getAgentForRead({ assistant_id: assistantId, tenant_id, thread_id: "" });
|
|
5719
6420
|
const imageData = await agent.get_draw_graph();
|
|
5720
6421
|
reply.header("Content-Type", "application/json").send({
|
|
5721
6422
|
image: imageData
|
|
@@ -5852,6 +6553,21 @@ var import_uuid = require("uuid");
|
|
|
5852
6553
|
var import_core3 = require("@axiom-lattice/core");
|
|
5853
6554
|
var import_protocols2 = require("@axiom-lattice/protocols");
|
|
5854
6555
|
|
|
6556
|
+
// src/utils/agentScope.ts
|
|
6557
|
+
function headerValue(value) {
|
|
6558
|
+
if (Array.isArray(value)) return value[0];
|
|
6559
|
+
return value;
|
|
6560
|
+
}
|
|
6561
|
+
function resolveAgentScope(request) {
|
|
6562
|
+
const workspace = headerValue(request.headers["x-workspace-id"]);
|
|
6563
|
+
const project = headerValue(request.headers["x-project-id"]);
|
|
6564
|
+
return {
|
|
6565
|
+
tenant_id: headerValue(request.headers["x-tenant-id"]),
|
|
6566
|
+
workspace_id: workspace || "default",
|
|
6567
|
+
project_id: project || void 0
|
|
6568
|
+
};
|
|
6569
|
+
}
|
|
6570
|
+
|
|
5855
6571
|
// src/services/agents/ScopedAgentExecution.ts
|
|
5856
6572
|
async function executeScopedAgentMessage(agent, request, stopTypes, options) {
|
|
5857
6573
|
const { messageId } = options === void 0 ? await agent.addMessage(request) : await agent.addMessage(request, options.queueMode);
|
|
@@ -5935,6 +6651,24 @@ async function writeSse(raw, value, closed) {
|
|
|
5935
6651
|
}
|
|
5936
6652
|
|
|
5937
6653
|
// src/controllers/run.ts
|
|
6654
|
+
var replicaHeader = () => ({ [import_protocols2.REPLICA_HEADER]: (0, import_core3.getReplicaId)() });
|
|
6655
|
+
var exposeHeaders = `${import_protocols2.REPLICA_HEADER}, ${import_protocols2.AFFINITY_ECHO_HEADER}`;
|
|
6656
|
+
function applyAffinityEcho(request, reply) {
|
|
6657
|
+
for (const [name, value] of Object.entries((0, import_protocols2.affinityEchoHeaders)(request.headers[import_protocols2.AGENT_AFFINITY_HEADER]))) {
|
|
6658
|
+
reply.header(name, value);
|
|
6659
|
+
}
|
|
6660
|
+
}
|
|
6661
|
+
var AFFINITY_GRACE_MS = Number.isFinite(Number(process.env.AXIOM_AFFINITY_GRACE_MS)) ? Number(process.env.AXIOM_AFFINITY_GRACE_MS) : 500;
|
|
6662
|
+
async function peerOwnsThread(input) {
|
|
6663
|
+
if (!process.env.AXIOM_REPLICA_ID) return null;
|
|
6664
|
+
if (!input.tenant_id || !input.assistant_id || !input.thread_id) return null;
|
|
6665
|
+
const owner = await (0, import_core3.getThreadRunOwner)({
|
|
6666
|
+
tenantId: input.tenant_id,
|
|
6667
|
+
assistantId: input.assistant_id,
|
|
6668
|
+
threadId: input.thread_id
|
|
6669
|
+
});
|
|
6670
|
+
return owner && owner !== (0, import_core3.getReplicaId)() ? owner : null;
|
|
6671
|
+
}
|
|
5938
6672
|
function getUserId2(request) {
|
|
5939
6673
|
const authUser = request.user;
|
|
5940
6674
|
if (authUser?.id) return authUser.id;
|
|
@@ -5953,9 +6687,7 @@ var createRun = async (request, reply) => {
|
|
|
5953
6687
|
mode,
|
|
5954
6688
|
...input
|
|
5955
6689
|
} = request.body;
|
|
5956
|
-
const tenant_id = request
|
|
5957
|
-
const workspace_id = request.headers["x-workspace-id"];
|
|
5958
|
-
const project_id = request.headers["x-project-id"];
|
|
6690
|
+
const { tenant_id, workspace_id, project_id } = resolveAgentScope(request);
|
|
5959
6691
|
const x_request_id = request.headers["x-request-id"] || (0, import_uuid.v4)();
|
|
5960
6692
|
const user_id = getUserId2(request);
|
|
5961
6693
|
const mergedConfig = {
|
|
@@ -5963,6 +6695,7 @@ var createRun = async (request, reply) => {
|
|
|
5963
6695
|
...user_id && { user_id }
|
|
5964
6696
|
};
|
|
5965
6697
|
if (!assistant_id) {
|
|
6698
|
+
applyAffinityEcho(request, reply);
|
|
5966
6699
|
reply.status(400).send({
|
|
5967
6700
|
success: false,
|
|
5968
6701
|
error: "\u52A9\u624BID\u662F\u5FC5\u9700\u7684"
|
|
@@ -5984,6 +6717,8 @@ var createRun = async (request, reply) => {
|
|
|
5984
6717
|
command,
|
|
5985
6718
|
custom_run_config: mergedConfig
|
|
5986
6719
|
}, mode);
|
|
6720
|
+
reply.header(import_protocols2.REPLICA_HEADER, (0, import_core3.getReplicaId)());
|
|
6721
|
+
applyAffinityEcho(request, reply);
|
|
5987
6722
|
reply.status(202).send({
|
|
5988
6723
|
success: true,
|
|
5989
6724
|
messageId: result.messageId,
|
|
@@ -5997,7 +6732,10 @@ var createRun = async (request, reply) => {
|
|
|
5997
6732
|
"Content-Type": "text/event-stream",
|
|
5998
6733
|
"Cache-Control": "no-cache",
|
|
5999
6734
|
Connection: "keep-alive",
|
|
6000
|
-
"Access-Control-Allow-Origin": "*"
|
|
6735
|
+
"Access-Control-Allow-Origin": "*",
|
|
6736
|
+
"Access-Control-Expose-Headers": exposeHeaders,
|
|
6737
|
+
...replicaHeader(),
|
|
6738
|
+
...(0, import_protocols2.affinityEchoHeaders)(request.headers[import_protocols2.AGENT_AFFINITY_HEADER])
|
|
6001
6739
|
});
|
|
6002
6740
|
try {
|
|
6003
6741
|
const messageInput = message_id ? { ...input, id: message_id } : input;
|
|
@@ -6008,6 +6746,18 @@ var createRun = async (request, reply) => {
|
|
|
6008
6746
|
}, [import_protocols2.MessageChunkTypes.MESSAGE_COMPLETED, import_protocols2.MessageChunkTypes.INTERRUPT, import_protocols2.MessageChunkTypes.MESSAGE_FAILED], {
|
|
6009
6747
|
queueMode: mode
|
|
6010
6748
|
});
|
|
6749
|
+
let peer = await peerOwnsThread({ tenant_id, assistant_id, thread_id });
|
|
6750
|
+
if (peer) {
|
|
6751
|
+
await new Promise((resolve4) => setTimeout(resolve4, AFFINITY_GRACE_MS));
|
|
6752
|
+
peer = await peerOwnsThread({ tenant_id, assistant_id, thread_id });
|
|
6753
|
+
}
|
|
6754
|
+
if (peer) {
|
|
6755
|
+
reply.raw.write(`data: ${JSON.stringify((0, import_protocols2.buildAffinityMissChunk)(peer, thread_id))}
|
|
6756
|
+
|
|
6757
|
+
`);
|
|
6758
|
+
reply.raw.end();
|
|
6759
|
+
return;
|
|
6760
|
+
}
|
|
6011
6761
|
await pipeAsyncIterableToSse(reply.raw, result.stream, {
|
|
6012
6762
|
onError: (error) => [{
|
|
6013
6763
|
type: "error",
|
|
@@ -6039,12 +6789,15 @@ var createRun = async (request, reply) => {
|
|
|
6039
6789
|
command,
|
|
6040
6790
|
custom_run_config: mergedConfig
|
|
6041
6791
|
});
|
|
6792
|
+
reply.header(import_protocols2.REPLICA_HEADER, (0, import_core3.getReplicaId)());
|
|
6793
|
+
applyAffinityEcho(request, reply);
|
|
6042
6794
|
reply.status(200).send({
|
|
6043
6795
|
success: true,
|
|
6044
6796
|
...result
|
|
6045
6797
|
});
|
|
6046
6798
|
}
|
|
6047
6799
|
} catch (error) {
|
|
6800
|
+
applyAffinityEcho(request, reply);
|
|
6048
6801
|
reply.status(500).send({
|
|
6049
6802
|
success: false,
|
|
6050
6803
|
error: `\u521B\u5EFA\u8FD0\u884C\u65F6\u53D1\u751F\u9519\u8BEF: ${error.message}`
|
|
@@ -6054,9 +6807,7 @@ var createRun = async (request, reply) => {
|
|
|
6054
6807
|
var resumeStream = async (request, reply) => {
|
|
6055
6808
|
try {
|
|
6056
6809
|
const { thread_id, message_id, assistant_id, known_content, poll_interval } = request.body;
|
|
6057
|
-
const tenant_id = request
|
|
6058
|
-
const workspace_id = request.headers["x-workspace-id"];
|
|
6059
|
-
const project_id = request.headers["x-project-id"];
|
|
6810
|
+
const { tenant_id, workspace_id, project_id } = resolveAgentScope(request);
|
|
6060
6811
|
if (!thread_id || !message_id || !assistant_id || known_content === void 0) {
|
|
6061
6812
|
reply.status(400).send({
|
|
6062
6813
|
success: false,
|
|
@@ -6069,9 +6820,20 @@ var resumeStream = async (request, reply) => {
|
|
|
6069
6820
|
"Content-Type": "text/event-stream",
|
|
6070
6821
|
"Cache-Control": "no-cache",
|
|
6071
6822
|
Connection: "keep-alive",
|
|
6072
|
-
"Access-Control-Allow-Origin": "*"
|
|
6823
|
+
"Access-Control-Allow-Origin": "*",
|
|
6824
|
+
"Access-Control-Expose-Headers": exposeHeaders,
|
|
6825
|
+
...replicaHeader(),
|
|
6826
|
+
...(0, import_protocols2.affinityEchoHeaders)(request.headers[import_protocols2.AGENT_AFFINITY_HEADER])
|
|
6073
6827
|
});
|
|
6074
6828
|
try {
|
|
6829
|
+
const peer = await peerOwnsThread({ tenant_id, assistant_id, thread_id });
|
|
6830
|
+
if (peer) {
|
|
6831
|
+
reply.raw.write(`data: ${JSON.stringify((0, import_protocols2.buildAffinityMissChunk)(peer, thread_id))}
|
|
6832
|
+
|
|
6833
|
+
`);
|
|
6834
|
+
reply.raw.end();
|
|
6835
|
+
return;
|
|
6836
|
+
}
|
|
6075
6837
|
const agent = import_core3.agentInstanceManager.getAgent({
|
|
6076
6838
|
assistant_id,
|
|
6077
6839
|
thread_id,
|
|
@@ -6114,9 +6876,7 @@ var resumeStream = async (request, reply) => {
|
|
|
6114
6876
|
var abortRun = async (request, reply) => {
|
|
6115
6877
|
try {
|
|
6116
6878
|
const { assistantId, threadId } = request.params;
|
|
6117
|
-
const tenant_id = request
|
|
6118
|
-
const workspace_id = request.headers["x-workspace-id"] || "default";
|
|
6119
|
-
const project_id = request.headers["x-project-id"] || "default";
|
|
6879
|
+
const { tenant_id, workspace_id, project_id } = resolveAgentScope(request);
|
|
6120
6880
|
const agent = import_core3.agentInstanceManager.getAgent({
|
|
6121
6881
|
assistant_id: assistantId,
|
|
6122
6882
|
thread_id: threadId,
|
|
@@ -6124,12 +6884,22 @@ var abortRun = async (request, reply) => {
|
|
|
6124
6884
|
workspace_id,
|
|
6125
6885
|
project_id
|
|
6126
6886
|
});
|
|
6887
|
+
const peer = await peerOwnsThread({ tenant_id, assistant_id: assistantId, thread_id: threadId });
|
|
6888
|
+
if (peer) {
|
|
6889
|
+
reply.header(import_protocols2.REPLICA_HEADER, (0, import_core3.getReplicaId)());
|
|
6890
|
+
applyAffinityEcho(request, reply);
|
|
6891
|
+
reply.status(409).send({ success: false, code: import_protocols2.AFFINITY_MISS_CODE, owner: peer, threadId });
|
|
6892
|
+
return;
|
|
6893
|
+
}
|
|
6127
6894
|
await agent.abort();
|
|
6895
|
+
reply.header(import_protocols2.REPLICA_HEADER, (0, import_core3.getReplicaId)());
|
|
6896
|
+
applyAffinityEcho(request, reply);
|
|
6128
6897
|
reply.status(200).send({
|
|
6129
6898
|
success: true,
|
|
6130
6899
|
message: "Agent aborted"
|
|
6131
6900
|
});
|
|
6132
6901
|
} catch (error) {
|
|
6902
|
+
applyAffinityEcho(request, reply);
|
|
6133
6903
|
reply.status(500).send({
|
|
6134
6904
|
success: false,
|
|
6135
6905
|
error: `Abort failed: ${error.message}`
|
|
@@ -6139,9 +6909,7 @@ var abortRun = async (request, reply) => {
|
|
|
6139
6909
|
var recoverRun = async (request, reply) => {
|
|
6140
6910
|
try {
|
|
6141
6911
|
const { assistantId, threadId } = request.params;
|
|
6142
|
-
const tenant_id = request
|
|
6143
|
-
const workspace_id = request.headers["x-workspace-id"] || "default";
|
|
6144
|
-
const project_id = request.headers["x-project-id"];
|
|
6912
|
+
const { tenant_id, workspace_id, project_id } = resolveAgentScope(request);
|
|
6145
6913
|
const agent = import_core3.agentInstanceManager.getAgent({
|
|
6146
6914
|
assistant_id: assistantId,
|
|
6147
6915
|
thread_id: threadId,
|
|
@@ -6149,13 +6917,17 @@ var recoverRun = async (request, reply) => {
|
|
|
6149
6917
|
workspace_id,
|
|
6150
6918
|
project_id
|
|
6151
6919
|
});
|
|
6152
|
-
const { status } = await agent.resumeTask();
|
|
6920
|
+
const { status, leaseContended } = await agent.resumeTask();
|
|
6921
|
+
reply.header(import_protocols2.REPLICA_HEADER, (0, import_core3.getReplicaId)());
|
|
6922
|
+
applyAffinityEcho(request, reply);
|
|
6153
6923
|
reply.status(200).send({
|
|
6154
6924
|
success: true,
|
|
6155
6925
|
threadId,
|
|
6156
|
-
status
|
|
6926
|
+
status,
|
|
6927
|
+
...leaseContended ? { code: import_protocols2.AFFINITY_MISS_CODE } : {}
|
|
6157
6928
|
});
|
|
6158
6929
|
} catch (error) {
|
|
6930
|
+
applyAffinityEcho(request, reply);
|
|
6159
6931
|
reply.status(500).send({
|
|
6160
6932
|
success: false,
|
|
6161
6933
|
error: `Recover failed: ${error.message}`
|
|
@@ -6229,7 +7001,7 @@ var getAllMemoryItems = async (request, reply) => {
|
|
|
6229
7001
|
});
|
|
6230
7002
|
return;
|
|
6231
7003
|
}
|
|
6232
|
-
const agent = import_core4.agentInstanceManager.
|
|
7004
|
+
const agent = import_core4.agentInstanceManager.getAgentForRead({ assistant_id: assistantId, tenant_id, thread_id });
|
|
6233
7005
|
const result = await agent.getCurrentMessages();
|
|
6234
7006
|
if (!result) {
|
|
6235
7007
|
reply.status(500).send(result);
|
|
@@ -6261,7 +7033,7 @@ var getAgentState = async (request, reply) => {
|
|
|
6261
7033
|
return;
|
|
6262
7034
|
}
|
|
6263
7035
|
const tenant_id = request.headers["x-tenant-id"];
|
|
6264
|
-
const agent = import_core4.agentInstanceManager.
|
|
7036
|
+
const agent = import_core4.agentInstanceManager.getAgentForRead({ assistant_id: assistantId, tenant_id, thread_id });
|
|
6265
7037
|
const result = await agent.getCurrentState();
|
|
6266
7038
|
const pendingMessages = await agent.getPendingMessages();
|
|
6267
7039
|
if (!result) {
|
|
@@ -8072,7 +8844,7 @@ async function getInboxItems(request, reply) {
|
|
|
8072
8844
|
store2.getRunSteps(r.id).catch(() => []),
|
|
8073
8845
|
(async () => {
|
|
8074
8846
|
try {
|
|
8075
|
-
return import_core15.agentInstanceManager.
|
|
8847
|
+
return import_core15.agentInstanceManager.getAgentForRead({
|
|
8076
8848
|
assistant_id: r.assistantId,
|
|
8077
8849
|
thread_id: r.threadId,
|
|
8078
8850
|
tenant_id: r.tenantId
|
|
@@ -10231,9 +11003,9 @@ function isRoomPresenceMetadata(metadata, expected) {
|
|
|
10231
11003
|
// src/services/collaboration/RoomCoordinatorEnsurer.ts
|
|
10232
11004
|
var RoomCoordinatorEnsureError = class extends Error {
|
|
10233
11005
|
/** Creates a typed ensure failure with the underlying store outcome. */
|
|
10234
|
-
constructor(
|
|
10235
|
-
super(`Room coordinator could not be ensured: ${
|
|
10236
|
-
this.outcome =
|
|
11006
|
+
constructor(outcome2) {
|
|
11007
|
+
super(`Room coordinator could not be ensured: ${outcome2}`);
|
|
11008
|
+
this.outcome = outcome2;
|
|
10237
11009
|
this.name = "RoomCoordinatorEnsureError";
|
|
10238
11010
|
}
|
|
10239
11011
|
};
|
|
@@ -12720,6 +13492,43 @@ function connectionRoutes(fastify2) {
|
|
|
12720
13492
|
// src/controllers/mcp-configs.ts
|
|
12721
13493
|
var import_core33 = require("@axiom-lattice/core");
|
|
12722
13494
|
var import_crypto8 = require("crypto");
|
|
13495
|
+
|
|
13496
|
+
// src/services/mcpConfigSync.ts
|
|
13497
|
+
var MCP_CONFIG_CHANGED_TOPIC = "mcp-config-changed";
|
|
13498
|
+
async function publishMcpConfigChanged(outbox, owner, tenantId, serverKey) {
|
|
13499
|
+
if (!tenantId || !serverKey) return;
|
|
13500
|
+
try {
|
|
13501
|
+
await outbox.append({
|
|
13502
|
+
topic: MCP_CONFIG_CHANGED_TOPIC,
|
|
13503
|
+
payload: { tenantId, serverKey },
|
|
13504
|
+
originReplicaId: owner
|
|
13505
|
+
});
|
|
13506
|
+
} catch {
|
|
13507
|
+
}
|
|
13508
|
+
}
|
|
13509
|
+
async function reconcileMcpConfigChange(payload, deps) {
|
|
13510
|
+
const tenantId = payload?.tenantId;
|
|
13511
|
+
const serverKey = payload?.serverKey;
|
|
13512
|
+
if (typeof tenantId !== "string" || tenantId.length === 0) return;
|
|
13513
|
+
if (typeof serverKey !== "string" || serverKey.length === 0) return;
|
|
13514
|
+
const config = await deps.store.getConfigByKey(tenantId, serverKey);
|
|
13515
|
+
if (!config || config.status !== "connected") {
|
|
13516
|
+
if (deps.manager.hasServer(tenantId, serverKey)) {
|
|
13517
|
+
await deps.manager.removeServer(tenantId, serverKey);
|
|
13518
|
+
}
|
|
13519
|
+
return;
|
|
13520
|
+
}
|
|
13521
|
+
const connection = deps.convertToConnection(config.config);
|
|
13522
|
+
deps.manager.registerServer(tenantId, serverKey, connection, {
|
|
13523
|
+
timeoutMs: config.config.timeout,
|
|
13524
|
+
maxAttempts: config.config.retryAttempts,
|
|
13525
|
+
selectedTools: config.selectedTools
|
|
13526
|
+
});
|
|
13527
|
+
await deps.manager.ensureConnected(tenantId, serverKey);
|
|
13528
|
+
await deps.manager.registerToolsToToolLattice(tenantId, serverKey, config.selectedTools);
|
|
13529
|
+
}
|
|
13530
|
+
|
|
13531
|
+
// src/controllers/mcp-configs.ts
|
|
12723
13532
|
function getTenantId11(request) {
|
|
12724
13533
|
const userTenantId = request.user?.tenantId;
|
|
12725
13534
|
if (userTenantId) {
|
|
@@ -12727,6 +13536,14 @@ function getTenantId11(request) {
|
|
|
12727
13536
|
}
|
|
12728
13537
|
return request.headers["x-tenant-id"] || "default";
|
|
12729
13538
|
}
|
|
13539
|
+
function broadcastMcpConfigChanged(tenantId, serverKey) {
|
|
13540
|
+
if (!tenantId || !serverKey) return;
|
|
13541
|
+
try {
|
|
13542
|
+
const outbox = (0, import_core33.getStoreLattice)("default", "outbox").store;
|
|
13543
|
+
void publishMcpConfigChanged(outbox, (0, import_core33.getReplicaId)(), tenantId, serverKey);
|
|
13544
|
+
} catch {
|
|
13545
|
+
}
|
|
13546
|
+
}
|
|
12730
13547
|
async function getMcpServerConfigList(request, reply) {
|
|
12731
13548
|
const tenantId = getTenantId11(request);
|
|
12732
13549
|
try {
|
|
@@ -12804,6 +13621,7 @@ async function createMcpServerConfig(request, reply) {
|
|
|
12804
13621
|
await store2.updateConfig(tenantId, id3, { status: "error" });
|
|
12805
13622
|
config.status = "error";
|
|
12806
13623
|
}
|
|
13624
|
+
broadcastMcpConfigChanged(tenantId, config.key);
|
|
12807
13625
|
reply.code(201);
|
|
12808
13626
|
return {
|
|
12809
13627
|
success: true,
|
|
@@ -12833,7 +13651,9 @@ async function updateMcpServerConfig(request, reply) {
|
|
|
12833
13651
|
message: "MCP server configuration not found"
|
|
12834
13652
|
};
|
|
12835
13653
|
}
|
|
12836
|
-
const
|
|
13654
|
+
const configChanged = updates.config !== void 0;
|
|
13655
|
+
const toolsChanged = updates.selectedTools !== void 0;
|
|
13656
|
+
const statusChanged = updates.status !== void 0;
|
|
12837
13657
|
const updated = await store2.updateConfig(tenantId, existing.id, updates);
|
|
12838
13658
|
if (!updated) {
|
|
12839
13659
|
return {
|
|
@@ -12841,7 +13661,7 @@ async function updateMcpServerConfig(request, reply) {
|
|
|
12841
13661
|
message: "Failed to update MCP server configuration"
|
|
12842
13662
|
};
|
|
12843
13663
|
}
|
|
12844
|
-
if (
|
|
13664
|
+
if (configChanged) {
|
|
12845
13665
|
try {
|
|
12846
13666
|
const connection = (0, import_core33.convertToConnection)(updated.config);
|
|
12847
13667
|
import_core33.mcpManager.registerServer(tenantId, key, connection, {
|
|
@@ -12853,11 +13673,27 @@ async function updateMcpServerConfig(request, reply) {
|
|
|
12853
13673
|
await store2.updateConfig(tenantId, existing.id, { status: "connected" });
|
|
12854
13674
|
updated.status = "connected";
|
|
12855
13675
|
} catch (error) {
|
|
12856
|
-
console.warn("Failed to reconnect MCP server:", error);
|
|
12857
|
-
await store2.updateConfig(tenantId, existing.id, { status: "error" });
|
|
12858
|
-
updated.status = "error";
|
|
13676
|
+
console.warn("Failed to reconnect MCP server:", error);
|
|
13677
|
+
await store2.updateConfig(tenantId, existing.id, { status: "error" });
|
|
13678
|
+
updated.status = "error";
|
|
13679
|
+
}
|
|
13680
|
+
} else if (toolsChanged && import_core33.mcpManager.hasServer(tenantId, key)) {
|
|
13681
|
+
try {
|
|
13682
|
+
await import_core33.mcpManager.registerToolsToToolLattice(tenantId, key, updated.selectedTools);
|
|
13683
|
+
} catch (error) {
|
|
13684
|
+
console.warn("Failed to re-register MCP tools:", error);
|
|
13685
|
+
}
|
|
13686
|
+
}
|
|
13687
|
+
if (statusChanged && updated.status !== "connected" && import_core33.mcpManager.hasServer(tenantId, key)) {
|
|
13688
|
+
try {
|
|
13689
|
+
await import_core33.mcpManager.removeServer(tenantId, key);
|
|
13690
|
+
} catch (error) {
|
|
13691
|
+
console.warn("Failed to remove MCP server:", error);
|
|
12859
13692
|
}
|
|
12860
13693
|
}
|
|
13694
|
+
if (configChanged || toolsChanged || statusChanged) {
|
|
13695
|
+
broadcastMcpConfigChanged(tenantId, key);
|
|
13696
|
+
}
|
|
12861
13697
|
return {
|
|
12862
13698
|
success: true,
|
|
12863
13699
|
message: "MCP server configuration updated successfully",
|
|
@@ -12906,6 +13742,7 @@ async function deleteMcpServerConfig(request, reply) {
|
|
|
12906
13742
|
message: "Failed to delete MCP server configuration"
|
|
12907
13743
|
};
|
|
12908
13744
|
}
|
|
13745
|
+
broadcastMcpConfigChanged(tenantId, configKey);
|
|
12909
13746
|
return {
|
|
12910
13747
|
success: true,
|
|
12911
13748
|
message: "MCP server configuration deleted successfully"
|
|
@@ -12980,12 +13817,17 @@ async function listMcpServerTools(request, reply) {
|
|
|
12980
13817
|
message: "MCP server configuration not found"
|
|
12981
13818
|
};
|
|
12982
13819
|
}
|
|
12983
|
-
|
|
13820
|
+
const wasConnected = import_core33.mcpManager.isServerConnected(tenantId, key);
|
|
13821
|
+
if (!wasConnected) {
|
|
12984
13822
|
await connectAndRegisterTools(config);
|
|
12985
13823
|
}
|
|
12986
|
-
|
|
13824
|
+
const statusStale = config.status !== "connected";
|
|
13825
|
+
if (statusStale) {
|
|
12987
13826
|
await store2.updateConfig(tenantId, config.id, { status: "connected" });
|
|
12988
13827
|
}
|
|
13828
|
+
if (!wasConnected || statusStale) {
|
|
13829
|
+
broadcastMcpConfigChanged(tenantId, key);
|
|
13830
|
+
}
|
|
12989
13831
|
const tools = await import_core33.mcpManager.getServerTools(tenantId, key);
|
|
12990
13832
|
return {
|
|
12991
13833
|
success: true,
|
|
@@ -13020,6 +13862,7 @@ async function connectMcpServer(request, reply) {
|
|
|
13020
13862
|
const updated = await store2.updateConfig(tenantId, config.id, {
|
|
13021
13863
|
status: "connected"
|
|
13022
13864
|
});
|
|
13865
|
+
broadcastMcpConfigChanged(tenantId, key);
|
|
13023
13866
|
return {
|
|
13024
13867
|
success: true,
|
|
13025
13868
|
message: "MCP server connected successfully",
|
|
@@ -13033,6 +13876,7 @@ async function connectMcpServer(request, reply) {
|
|
|
13033
13876
|
if (config) {
|
|
13034
13877
|
await store2.updateConfig(tenantId, config.id, { status: "error" });
|
|
13035
13878
|
}
|
|
13879
|
+
broadcastMcpConfigChanged(tenantId, key);
|
|
13036
13880
|
return {
|
|
13037
13881
|
success: false,
|
|
13038
13882
|
message: `Failed to connect MCP server: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
@@ -13059,6 +13903,7 @@ async function disconnectMcpServer(request, reply) {
|
|
|
13059
13903
|
const updated = await store2.updateConfig(tenantId, config.id, {
|
|
13060
13904
|
status: "disconnected"
|
|
13061
13905
|
});
|
|
13906
|
+
broadcastMcpConfigChanged(tenantId, key);
|
|
13062
13907
|
return {
|
|
13063
13908
|
success: true,
|
|
13064
13909
|
message: "MCP server disconnected successfully",
|
|
@@ -15309,7 +16154,7 @@ function verifyLarkParsedBody(body, config) {
|
|
|
15309
16154
|
}
|
|
15310
16155
|
return extractVerificationToken(body) === config.verificationToken;
|
|
15311
16156
|
}
|
|
15312
|
-
function
|
|
16157
|
+
function headerValue2(request, name) {
|
|
15313
16158
|
const value = request.headers[name];
|
|
15314
16159
|
return Array.isArray(value) ? value[0] : value;
|
|
15315
16160
|
}
|
|
@@ -15317,9 +16162,9 @@ function verifyLarkRequestSignature(request, config) {
|
|
|
15317
16162
|
if (!config.encryptKey) {
|
|
15318
16163
|
return true;
|
|
15319
16164
|
}
|
|
15320
|
-
const timestamp =
|
|
15321
|
-
const nonce =
|
|
15322
|
-
const signature =
|
|
16165
|
+
const timestamp = headerValue2(request, "x-lark-request-timestamp");
|
|
16166
|
+
const nonce = headerValue2(request, "x-lark-request-nonce");
|
|
16167
|
+
const signature = headerValue2(request, "x-lark-signature");
|
|
15323
16168
|
if (!timestamp || !nonce || !signature) {
|
|
15324
16169
|
return false;
|
|
15325
16170
|
}
|
|
@@ -15577,8 +16422,8 @@ function snapshotPlainObject(value) {
|
|
|
15577
16422
|
}
|
|
15578
16423
|
}
|
|
15579
16424
|
async function getInstallationStore() {
|
|
15580
|
-
const { getStoreLattice:
|
|
15581
|
-
const store2 =
|
|
16425
|
+
const { getStoreLattice: getStoreLattice39 } = await import("@axiom-lattice/core");
|
|
16426
|
+
const store2 = getStoreLattice39("default", "channelInstallation").store;
|
|
15582
16427
|
if (store2) return store2;
|
|
15583
16428
|
const { PostgreSQLChannelInstallationStore } = await import("@axiom-lattice/pg-stores");
|
|
15584
16429
|
const databaseUrl = process.env.DATABASE_URL;
|
|
@@ -16720,7 +17565,7 @@ function registerTaskRoutes(app2, controller) {
|
|
|
16720
17565
|
}
|
|
16721
17566
|
|
|
16722
17567
|
// src/routes/index.ts
|
|
16723
|
-
var
|
|
17568
|
+
var import_core54 = require("@axiom-lattice/core");
|
|
16724
17569
|
|
|
16725
17570
|
// src/controllers/tasks.ts
|
|
16726
17571
|
var import_protocols13 = require("@axiom-lattice/protocols");
|
|
@@ -16929,40 +17774,8 @@ function isTaskFileRef(value) {
|
|
|
16929
17774
|
return !!row && typeof row.uri === "string" && !!row.uri && (row.name === void 0 || typeof row.name === "string") && (row.mimeType === void 0 || typeof row.mimeType === "string") && (row.addedBy === void 0 || row.addedBy === "user" || row.addedBy === "agent");
|
|
16930
17775
|
}
|
|
16931
17776
|
|
|
16932
|
-
// src/services/collaboration/projectTaskScope.ts
|
|
16933
|
-
function isProjectLifecycleTask(task) {
|
|
16934
|
-
const source = task.context?.source;
|
|
16935
|
-
return typeof task.workspaceId === "string" && task.workspaceId.length > 0 && typeof task.projectId === "string" && task.projectId.length > 0 && (source === "project_room" || source === "project_task" || source === "user");
|
|
16936
|
-
}
|
|
16937
|
-
function isRosterExemptProject(project) {
|
|
16938
|
-
return project?.kind === "public";
|
|
16939
|
-
}
|
|
16940
|
-
function resolveTaskOwnerMembership(task, project, room, membership) {
|
|
16941
|
-
const active = membership && membership.status === "active" && membership.tenantId === task.tenantId && membership.workspaceId === task.workspaceId && membership.projectId === task.projectId && membership.assistantId === task.ownerId && membership.roomId === room.id;
|
|
16942
|
-
if (active) return membership;
|
|
16943
|
-
if (!isRosterExemptProject(project)) return void 0;
|
|
16944
|
-
return syntheticPublicProjectOwnerMembership(task, room);
|
|
16945
|
-
}
|
|
16946
|
-
function syntheticPublicProjectOwnerMembership(task, room) {
|
|
16947
|
-
const threadId = typeof task.context?.thread_id === "string" && task.context.thread_id.length > 0 ? task.context.thread_id : task.ownerId;
|
|
16948
|
-
return {
|
|
16949
|
-
id: `public-project-owner:${task.projectId}:${task.ownerId}`,
|
|
16950
|
-
tenantId: task.tenantId,
|
|
16951
|
-
workspaceId: task.workspaceId,
|
|
16952
|
-
projectId: task.projectId,
|
|
16953
|
-
roomId: room.id,
|
|
16954
|
-
assistantId: task.ownerId,
|
|
16955
|
-
role: "specialist",
|
|
16956
|
-
title: task.ownerId,
|
|
16957
|
-
mentionName: task.ownerId,
|
|
16958
|
-
status: "active",
|
|
16959
|
-
roomThreadId: threadId,
|
|
16960
|
-
joinedAt: task.createdAt,
|
|
16961
|
-
updatedAt: task.updatedAt
|
|
16962
|
-
};
|
|
16963
|
-
}
|
|
16964
|
-
|
|
16965
17777
|
// src/services/collaboration/ProjectTaskThreadService.ts
|
|
17778
|
+
init_projectTaskScope();
|
|
16966
17779
|
var ProjectTaskThreadError = class extends Error {
|
|
16967
17780
|
/**
|
|
16968
17781
|
* @param code Stable machine-readable failure code.
|
|
@@ -17078,6 +17891,7 @@ var import_node_crypto9 = require("crypto");
|
|
|
17078
17891
|
var import_node_crypto8 = require("crypto");
|
|
17079
17892
|
var import_core44 = require("@axiom-lattice/core");
|
|
17080
17893
|
var import_protocols12 = require("@axiom-lattice/protocols");
|
|
17894
|
+
init_projectTaskScope();
|
|
17081
17895
|
|
|
17082
17896
|
// src/router/roomInterrupt.ts
|
|
17083
17897
|
var CLARIFY_FENCE = /^```clarify\n([\s\S]*?)\n```$/;
|
|
@@ -17330,18 +18144,22 @@ var ProjectTaskExecutionService = class {
|
|
|
17330
18144
|
input.inputMessageId,
|
|
17331
18145
|
true
|
|
17332
18146
|
);
|
|
18147
|
+
if (resumed.leaseContended) {
|
|
18148
|
+
settlement.cleanup();
|
|
18149
|
+
return { kind: "deferred", task: input.task, thread: input.thread, messageId: input.inputMessageId };
|
|
18150
|
+
}
|
|
17333
18151
|
if (resumed.status === import_core44.ThreadStatus.INTERRUPTED && settlement.tryClaim()) {
|
|
17334
18152
|
settlement.cleanup();
|
|
17335
|
-
const
|
|
17336
|
-
settlement.resolve(
|
|
17337
|
-
return
|
|
18153
|
+
const outcome2 = await this.settleInterruptedEvent(input.task, input.thread, input.inputMessageId);
|
|
18154
|
+
settlement.resolve(outcome2);
|
|
18155
|
+
return outcome2;
|
|
17338
18156
|
}
|
|
17339
18157
|
if ((resumed.status === import_core44.ThreadStatus.IDLE || resumed.status === import_core44.ThreadStatus.ERROR) && settlement.tryClaim()) {
|
|
17340
18158
|
settlement.cleanup();
|
|
17341
18159
|
const reason = resumed.status === import_core44.ThreadStatus.IDLE ? "Project task execution ended without lifecycle transition" : "Recovered Agent execution is in error state";
|
|
17342
|
-
const
|
|
17343
|
-
settlement.resolve(
|
|
17344
|
-
return
|
|
18160
|
+
const outcome2 = await this.settleEndedRecovery(input, reason);
|
|
18161
|
+
settlement.resolve(outcome2);
|
|
18162
|
+
return outcome2;
|
|
17345
18163
|
}
|
|
17346
18164
|
return await this.awaitSettlementCancellation(
|
|
17347
18165
|
settlement,
|
|
@@ -17353,7 +18171,7 @@ var ProjectTaskExecutionService = class {
|
|
|
17353
18171
|
} catch (error) {
|
|
17354
18172
|
if (!settlement.tryClaim()) return settlement.promise;
|
|
17355
18173
|
settlement.cleanup();
|
|
17356
|
-
const
|
|
18174
|
+
const outcome2 = {
|
|
17357
18175
|
kind: "failed",
|
|
17358
18176
|
task: input.task,
|
|
17359
18177
|
thread: input.thread,
|
|
@@ -17362,8 +18180,8 @@ var ProjectTaskExecutionService = class {
|
|
|
17362
18180
|
cause: "recovery_ended",
|
|
17363
18181
|
lifecycleHandled: false
|
|
17364
18182
|
};
|
|
17365
|
-
settlement.resolve(
|
|
17366
|
-
return
|
|
18183
|
+
settlement.resolve(outcome2);
|
|
18184
|
+
return outcome2;
|
|
17367
18185
|
}
|
|
17368
18186
|
}
|
|
17369
18187
|
/** Classifies one exact Task Thread queue fact with transition-safe repeated reads. */
|
|
@@ -17581,9 +18399,9 @@ var ProjectTaskExecutionService = class {
|
|
|
17581
18399
|
async claimDispatchFailure(settlement, task, thread, messageId, error) {
|
|
17582
18400
|
if (!settlement.tryClaim()) return settlement.promise;
|
|
17583
18401
|
settlement.cleanup();
|
|
17584
|
-
const
|
|
17585
|
-
settlement.resolve(
|
|
17586
|
-
return
|
|
18402
|
+
const outcome2 = await this.failSettledTaskAwaited(task, thread, messageId, error);
|
|
18403
|
+
settlement.resolve(outcome2);
|
|
18404
|
+
return outcome2;
|
|
17587
18405
|
}
|
|
17588
18406
|
armSettlement(task, thread, messageId) {
|
|
17589
18407
|
let claimed = false;
|
|
@@ -17674,9 +18492,9 @@ var ProjectTaskExecutionService = class {
|
|
|
17674
18492
|
} catch {
|
|
17675
18493
|
}
|
|
17676
18494
|
}
|
|
17677
|
-
const
|
|
17678
|
-
settlement.resolve(
|
|
17679
|
-
return
|
|
18495
|
+
const outcome2 = await this.compensateCancellation(task, thread, messageId, false);
|
|
18496
|
+
settlement.resolve(outcome2);
|
|
18497
|
+
return outcome2;
|
|
17680
18498
|
}
|
|
17681
18499
|
compensateCancellation(task, thread, messageId, abortAgent) {
|
|
17682
18500
|
if (abortAgent) {
|
|
@@ -19018,6 +19836,7 @@ var import_zod6 = require("zod");
|
|
|
19018
19836
|
// src/services/agent-web-app/AgentWebAppRuntimeService.ts
|
|
19019
19837
|
var import_node_crypto10 = require("crypto");
|
|
19020
19838
|
var import_protocols14 = require("@axiom-lattice/protocols");
|
|
19839
|
+
var import_core46 = require("@axiom-lattice/core");
|
|
19021
19840
|
init_task_file_refs();
|
|
19022
19841
|
function isRecord2(value) {
|
|
19023
19842
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -19180,6 +19999,20 @@ var AgentWebAppRuntimeService = class {
|
|
|
19180
19999
|
async resumeStream(webAppId, userId, threadId, messageId, selection) {
|
|
19181
20000
|
const runtime = await this.resolveRuntime(webAppId, selection);
|
|
19182
20001
|
await this.requireOwnedThread(runtime, userId, threadId);
|
|
20002
|
+
if (process.env.AXIOM_REPLICA_ID) {
|
|
20003
|
+
const owner = await (0, import_core46.getThreadRunOwner)({
|
|
20004
|
+
tenantId: runtime.webApp.tenantId,
|
|
20005
|
+
assistantId: runtime.webApp.assistantId,
|
|
20006
|
+
threadId
|
|
20007
|
+
});
|
|
20008
|
+
if (owner && owner !== (0, import_core46.getReplicaId)()) {
|
|
20009
|
+
return {
|
|
20010
|
+
stream: (async function* () {
|
|
20011
|
+
yield (0, import_protocols14.buildAffinityMissChunk)(owner, threadId);
|
|
20012
|
+
})()
|
|
20013
|
+
};
|
|
20014
|
+
}
|
|
20015
|
+
}
|
|
19183
20016
|
const agent = this.resolveAgent(runtime, threadId);
|
|
19184
20017
|
return { stream: agent.chunkStream(messageId, []) };
|
|
19185
20018
|
}
|
|
@@ -19525,6 +20358,7 @@ async function verifyWebAppToken(token, issuer, options = {}) {
|
|
|
19525
20358
|
|
|
19526
20359
|
// src/routes/agent-web-app-runtime.ts
|
|
19527
20360
|
var import_protocols15 = require("@axiom-lattice/protocols");
|
|
20361
|
+
var import_core47 = require("@axiom-lattice/core");
|
|
19528
20362
|
var idSchema = import_zod6.z.string().min(1).max(128);
|
|
19529
20363
|
var paramsSchema = import_zod6.z.object({ webAppId: idSchema }).strict();
|
|
19530
20364
|
var threadParamsSchema = import_zod6.z.object({ webAppId: idSchema, threadId: idSchema }).strict();
|
|
@@ -19673,7 +20507,7 @@ function registerAgentWebAppRuntimeRoutes(app2, deps) {
|
|
|
19673
20507
|
const identity = await resolveRuntimeIdentity(request, webAppId, identities);
|
|
19674
20508
|
const input = streamBodySchema.parse(request.body);
|
|
19675
20509
|
const result = await deps.service.streamMessage(webAppId, identity.userId, threadId, withPreview(input, identity.preview));
|
|
19676
|
-
beginSse(reply);
|
|
20510
|
+
beginSse(reply, request);
|
|
19677
20511
|
await pipeNativeWebAppStream(reply.raw, result.stream);
|
|
19678
20512
|
} catch (error) {
|
|
19679
20513
|
return normalizeError2(reply, error);
|
|
@@ -19685,7 +20519,7 @@ function registerAgentWebAppRuntimeRoutes(app2, deps) {
|
|
|
19685
20519
|
const identity = await resolveRuntimeIdentity(request, webAppId, identities);
|
|
19686
20520
|
const input = streamBodySchema.parse(request.body);
|
|
19687
20521
|
const result = await deps.service.streamMessage(webAppId, identity.userId, threadId, withPreview(input, identity.preview));
|
|
19688
|
-
beginSse(reply);
|
|
20522
|
+
beginSse(reply, request);
|
|
19689
20523
|
await pipeAgentWebAppStream(reply.raw, result.stream, result);
|
|
19690
20524
|
} catch (error) {
|
|
19691
20525
|
return normalizeError2(reply, error);
|
|
@@ -19697,7 +20531,7 @@ function registerAgentWebAppRuntimeRoutes(app2, deps) {
|
|
|
19697
20531
|
const identity = await resolveRuntimeIdentity(request, webAppId, identities);
|
|
19698
20532
|
const { messageId, projectId, modelKey: modelKey2 } = resumeSchema.parse(request.body);
|
|
19699
20533
|
const result = await deps.service.resumeStream(webAppId, identity.userId, threadId, messageId, withPreview({ projectId, modelKey: modelKey2 }, identity.preview));
|
|
19700
|
-
beginSse(reply);
|
|
20534
|
+
beginSse(reply, request);
|
|
19701
20535
|
await pipeNativeWebAppStream(reply.raw, result.stream);
|
|
19702
20536
|
} catch (error) {
|
|
19703
20537
|
return normalizeError2(reply, error);
|
|
@@ -19730,7 +20564,7 @@ function registerAgentWebAppRuntimeRoutes(app2, deps) {
|
|
|
19730
20564
|
const identity = await resolveRuntimeIdentity(request, webAppId, identities);
|
|
19731
20565
|
const { projectId, modelKey: modelKey2, message, response } = resumeBodySchema.parse(request.body);
|
|
19732
20566
|
const result = await deps.service.resumeInterrupt(webAppId, identity.userId, threadId, interruptId, withPreview({ projectId, modelKey: modelKey2 }, identity.preview), { message, response });
|
|
19733
|
-
beginSse(reply);
|
|
20567
|
+
beginSse(reply, request);
|
|
19734
20568
|
await pipeAgentWebAppStream(reply.raw, result.stream, result);
|
|
19735
20569
|
} catch (error) {
|
|
19736
20570
|
return normalizeError2(reply, error);
|
|
@@ -19958,6 +20792,10 @@ function registerAgentWebAppRuntimeRoutes(app2, deps) {
|
|
|
19958
20792
|
if (!threadId) throw new AgentWebAppRuntimeError("INVALID_REQUEST", 400, "thread_id is required");
|
|
19959
20793
|
const content = body.messages.map((message) => message.content).join("\n");
|
|
19960
20794
|
const { messageId } = await deps.service.enqueueMessage(webAppId, identity.userId, threadId, content, { projectId: body.projectId, modelKey: body.modelKey });
|
|
20795
|
+
reply.header(import_protocols15.REPLICA_HEADER, (0, import_core47.getReplicaId)());
|
|
20796
|
+
for (const [name, value] of Object.entries((0, import_protocols15.affinityEchoHeaders)(request.headers[import_protocols15.AGENT_AFFINITY_HEADER]))) {
|
|
20797
|
+
reply.header(name, value);
|
|
20798
|
+
}
|
|
19961
20799
|
return reply.code(202).send({ success: true, messageId, queued: true });
|
|
19962
20800
|
} catch (error) {
|
|
19963
20801
|
return normalizeError2(reply, error);
|
|
@@ -19978,7 +20816,7 @@ function registerAgentWebAppRuntimeRoutes(app2, deps) {
|
|
|
19978
20816
|
const identity = await resolveRuntimeIdentity(request, webAppId, identities);
|
|
19979
20817
|
const body = resumeStreamSchema2.parse(request.body ?? {});
|
|
19980
20818
|
const result = await deps.service.resumeStream(webAppId, identity.userId, body.thread_id, body.message_id, { projectId: body.projectId, modelKey: body.modelKey });
|
|
19981
|
-
beginSse(reply);
|
|
20819
|
+
beginSse(reply, request);
|
|
19982
20820
|
await pipeNativeWebAppStream(reply.raw, result.stream);
|
|
19983
20821
|
} catch (error) {
|
|
19984
20822
|
return normalizeError2(reply, error);
|
|
@@ -20031,14 +20869,17 @@ async function pipeNativeWebAppStream(raw, stream) {
|
|
|
20031
20869
|
}]
|
|
20032
20870
|
});
|
|
20033
20871
|
}
|
|
20034
|
-
function beginSse(reply) {
|
|
20872
|
+
function beginSse(reply, request) {
|
|
20035
20873
|
reply.hijack();
|
|
20036
20874
|
reply.raw.writeHead(200, {
|
|
20037
20875
|
"Content-Type": "text/event-stream; charset=utf-8",
|
|
20038
20876
|
"Cache-Control": "no-cache, no-transform",
|
|
20039
20877
|
Connection: "keep-alive",
|
|
20040
20878
|
"X-Accel-Buffering": "no",
|
|
20041
|
-
"Access-Control-Allow-Origin": "*"
|
|
20879
|
+
"Access-Control-Allow-Origin": "*",
|
|
20880
|
+
"Access-Control-Expose-Headers": `${import_protocols15.REPLICA_HEADER}, ${import_protocols15.AFFINITY_ECHO_HEADER}`,
|
|
20881
|
+
[import_protocols15.REPLICA_HEADER]: (0, import_core47.getReplicaId)(),
|
|
20882
|
+
...(0, import_protocols15.affinityEchoHeaders)(request.headers[import_protocols15.AGENT_AFFINITY_HEADER])
|
|
20042
20883
|
});
|
|
20043
20884
|
}
|
|
20044
20885
|
async function handle2(reply, operation) {
|
|
@@ -20274,7 +21115,7 @@ var import_zod9 = require("zod");
|
|
|
20274
21115
|
|
|
20275
21116
|
// src/services/capability/CapabilityBundleService.ts
|
|
20276
21117
|
var import_zod8 = require("zod");
|
|
20277
|
-
var
|
|
21118
|
+
var import_core48 = require("@axiom-lattice/core");
|
|
20278
21119
|
var CapabilityBundleServiceError = class extends Error {
|
|
20279
21120
|
constructor(code, message, statusCode) {
|
|
20280
21121
|
super(message);
|
|
@@ -20315,7 +21156,7 @@ function projectBundleIds(config) {
|
|
|
20315
21156
|
return [...value];
|
|
20316
21157
|
}
|
|
20317
21158
|
function issue(error) {
|
|
20318
|
-
if (error instanceof
|
|
21159
|
+
if (error instanceof import_core48.CapabilityBundleMergeError || error instanceof import_core48.CapabilityBundleValidationError) return { code: error instanceof import_core48.CapabilityBundleValidationError && error.code === "CAPABILITY_BUNDLE_INVALID_CONFIG" ? "INVALID_BUNDLE_CONFIG" : error.code, message: error.message, bundleId: error instanceof import_core48.CapabilityBundleMergeError ? error.bundleId : void 0, capabilityType: error.capabilityType, fieldPath: error.fieldPath };
|
|
20319
21160
|
return { code: "CAPABILITY_BUNDLE_CONFIGURATION_ERROR", message: error instanceof Error ? error.message : "Invalid capability bundle configuration" };
|
|
20320
21161
|
}
|
|
20321
21162
|
var CapabilityBundleService = class {
|
|
@@ -20328,7 +21169,7 @@ var CapabilityBundleService = class {
|
|
|
20328
21169
|
const errors = [];
|
|
20329
21170
|
for (const value of values) {
|
|
20330
21171
|
try {
|
|
20331
|
-
(0,
|
|
21172
|
+
(0, import_core48.validateCapabilityBundleInput)(value);
|
|
20332
21173
|
bundles.push(value);
|
|
20333
21174
|
} catch {
|
|
20334
21175
|
errors.push({ bundleId: value.id, code: "INVALID_BUNDLE_CONFIG", message: "Capability bundle record is invalid" });
|
|
@@ -20340,7 +21181,7 @@ var CapabilityBundleService = class {
|
|
|
20340
21181
|
const value = await this.deps.bundleStore.getById(tenantId, id3);
|
|
20341
21182
|
if (!value) throw new CapabilityBundleServiceError("BUNDLE_NOT_FOUND", "Capability bundle not found", 404);
|
|
20342
21183
|
try {
|
|
20343
|
-
(0,
|
|
21184
|
+
(0, import_core48.validateCapabilityBundleInput)(value);
|
|
20344
21185
|
} catch {
|
|
20345
21186
|
throw new CapabilityBundleServiceError("INVALID_BUNDLE_CONFIG", "Capability bundle record is invalid", 422);
|
|
20346
21187
|
}
|
|
@@ -20348,7 +21189,7 @@ var CapabilityBundleService = class {
|
|
|
20348
21189
|
}
|
|
20349
21190
|
async create(tenantId, input) {
|
|
20350
21191
|
rejectStableKey(input);
|
|
20351
|
-
(0,
|
|
21192
|
+
(0, import_core48.validateCapabilityBundleInput)(input);
|
|
20352
21193
|
const value = input;
|
|
20353
21194
|
const name = value.name.trim();
|
|
20354
21195
|
const base = slugify(name);
|
|
@@ -20359,10 +21200,10 @@ var CapabilityBundleService = class {
|
|
|
20359
21200
|
let suffix = 2;
|
|
20360
21201
|
while (keys2.has(key)) key = `${base}-${suffix++}`;
|
|
20361
21202
|
const normalized = { ...value, key, name };
|
|
20362
|
-
(0,
|
|
21203
|
+
(0, import_core48.validateCapabilityBundleInput)(normalized);
|
|
20363
21204
|
try {
|
|
20364
21205
|
const result = await this.deps.bundleStore.create(tenantId, normalized);
|
|
20365
|
-
(0,
|
|
21206
|
+
(0, import_core48.validateCapabilityBundleInput)(result);
|
|
20366
21207
|
return result;
|
|
20367
21208
|
} catch (error) {
|
|
20368
21209
|
if (!isDuplicate(error)) throw error;
|
|
@@ -20373,16 +21214,16 @@ var CapabilityBundleService = class {
|
|
|
20373
21214
|
}
|
|
20374
21215
|
async update(tenantId, id3, input) {
|
|
20375
21216
|
rejectStableKey(input);
|
|
20376
|
-
(0,
|
|
21217
|
+
(0, import_core48.validateCapabilityBundleInput)(input, { partial: true });
|
|
20377
21218
|
if (!input || typeof input !== "object" || Array.isArray(input) || typeof input.expectedUpdatedAt !== "string" || !input.expectedUpdatedAt.trim()) throw new CapabilityBundleServiceError("INVALID_BUNDLE_CONFIG", "expectedUpdatedAt is required for capability bundle updates", 400);
|
|
20378
21219
|
const value = input;
|
|
20379
21220
|
const normalized = { ...value, ...value.name === void 0 ? {} : { name: value.name.trim() }, ...Object.prototype.hasOwnProperty.call(value, "description") ? { description: value.description?.trim() || void 0 } : {} };
|
|
20380
|
-
(0,
|
|
21221
|
+
(0, import_core48.validateCapabilityBundleInput)(normalized, { partial: true });
|
|
20381
21222
|
try {
|
|
20382
21223
|
const result = await this.deps.bundleStore.update(tenantId, id3, normalized);
|
|
20383
21224
|
if (!result) throw new CapabilityBundleServiceError("BUNDLE_NOT_FOUND", "Capability bundle not found", 404);
|
|
20384
21225
|
if ("status" in result && result.status === "conflict") throw new CapabilityBundleServiceError("BUNDLE_CONFLICT", "Capability bundle changed after it was loaded; reload before saving", 409);
|
|
20385
|
-
(0,
|
|
21226
|
+
(0, import_core48.validateCapabilityBundleInput)(result);
|
|
20386
21227
|
return result;
|
|
20387
21228
|
} catch (error) {
|
|
20388
21229
|
if (error instanceof CapabilityBundleServiceError) throw error;
|
|
@@ -20417,8 +21258,8 @@ var CapabilityBundleService = class {
|
|
|
20417
21258
|
if (missing.length > 0) return { bundleIds: ids, capabilities: [], overrides: [], sources: [], warnings: [], errors: missing.map((id3) => ({ code: "BUNDLE_NOT_FOUND", message: `Persisted capability bundle '${id3}' is missing`, bundleId: id3 })), revision: "" };
|
|
20418
21259
|
try {
|
|
20419
21260
|
const ordered = ids.map((id3) => byId.get(id3));
|
|
20420
|
-
ordered.forEach((bundle) => (0,
|
|
20421
|
-
return (0,
|
|
21261
|
+
ordered.forEach((bundle) => (0, import_core48.validateCapabilityBundleInput)(bundle));
|
|
21262
|
+
return (0, import_core48.mergeCapabilityBundles)(ordered);
|
|
20422
21263
|
} catch (error) {
|
|
20423
21264
|
return { bundleIds: ids, capabilities: [], overrides: [], sources: [], warnings: [], errors: [issue(error)], revision: "" };
|
|
20424
21265
|
}
|
|
@@ -20451,7 +21292,7 @@ var CapabilityBundleService = class {
|
|
|
20451
21292
|
return ids.map((id3) => {
|
|
20452
21293
|
const value = byId.get(id3);
|
|
20453
21294
|
if (!value) throw new CapabilityBundleServiceError("BUNDLE_NOT_FOUND", "Capability bundle not found", 404);
|
|
20454
|
-
(0,
|
|
21295
|
+
(0, import_core48.validateCapabilityBundleInput)(value);
|
|
20455
21296
|
return value;
|
|
20456
21297
|
});
|
|
20457
21298
|
}
|
|
@@ -20466,7 +21307,7 @@ var CapabilityBundleService = class {
|
|
|
20466
21307
|
continue;
|
|
20467
21308
|
}
|
|
20468
21309
|
try {
|
|
20469
|
-
(0,
|
|
21310
|
+
(0, import_core48.validateCapabilityBundleInput)(bundle);
|
|
20470
21311
|
valid.push(bundle);
|
|
20471
21312
|
} catch (error) {
|
|
20472
21313
|
errors.push({ ...issue(error), bundleId: id3 });
|
|
@@ -20474,7 +21315,7 @@ var CapabilityBundleService = class {
|
|
|
20474
21315
|
}
|
|
20475
21316
|
let preview;
|
|
20476
21317
|
try {
|
|
20477
|
-
preview = (0,
|
|
21318
|
+
preview = (0, import_core48.mergeCapabilityBundles)(valid);
|
|
20478
21319
|
} catch (error) {
|
|
20479
21320
|
preview = { bundleIds: ids, capabilities: [], overrides: [], sources: [], warnings: [], errors: [issue(error)], revision: "" };
|
|
20480
21321
|
}
|
|
@@ -20626,7 +21467,7 @@ var import_zod11 = require("zod");
|
|
|
20626
21467
|
// src/services/model-provider/ModelProviderService.ts
|
|
20627
21468
|
var import_node_crypto14 = require("crypto");
|
|
20628
21469
|
var import_protocols16 = require("@axiom-lattice/protocols");
|
|
20629
|
-
var
|
|
21470
|
+
var import_core49 = require("@axiom-lattice/core");
|
|
20630
21471
|
|
|
20631
21472
|
// src/services/model-provider/errors.ts
|
|
20632
21473
|
var ModelProviderServiceError = class extends Error {
|
|
@@ -20639,6 +21480,17 @@ var ModelProviderServiceError = class extends Error {
|
|
|
20639
21480
|
this.name = "ModelProviderServiceError";
|
|
20640
21481
|
}
|
|
20641
21482
|
};
|
|
21483
|
+
var UPSTREAM_ERROR_CODES = {
|
|
21484
|
+
UPSTREAM_UNREACHABLE: true,
|
|
21485
|
+
UPSTREAM_AUTH_FAILED: true,
|
|
21486
|
+
UPSTREAM_REDIRECT_BLOCKED: true,
|
|
21487
|
+
UPSTREAM_INVALID_RESPONSE: true,
|
|
21488
|
+
UPSTREAM_RATE_LIMITED: true,
|
|
21489
|
+
UPSTREAM_TIMEOUT: true
|
|
21490
|
+
};
|
|
21491
|
+
function isUpstreamErrorCode(code) {
|
|
21492
|
+
return Object.prototype.hasOwnProperty.call(UPSTREAM_ERROR_CODES, code);
|
|
21493
|
+
}
|
|
20642
21494
|
|
|
20643
21495
|
// src/services/model-provider/discovery.ts
|
|
20644
21496
|
var MAX_DISCOVERED_MODELS = 1e3;
|
|
@@ -20914,6 +21766,33 @@ var ModelProviderService = class {
|
|
|
20914
21766
|
models
|
|
20915
21767
|
};
|
|
20916
21768
|
}
|
|
21769
|
+
/**
|
|
21770
|
+
* Hydrates the runtime model registry from the persisted provider catalog.
|
|
21771
|
+
*
|
|
21772
|
+
* @returns The model keys registered in this process.
|
|
21773
|
+
* @remarks Registers the Phase-1 (default tenant) enabled provider models so a
|
|
21774
|
+
* replica that did not perform discovery — or that restarted — can execute
|
|
21775
|
+
* them. Best-effort; the caller logs failures.
|
|
21776
|
+
*/
|
|
21777
|
+
async hydrateRegistry() {
|
|
21778
|
+
const tenantId = PHASE1_REGISTRY_TENANT;
|
|
21779
|
+
if (!this.shouldRegister(tenantId)) {
|
|
21780
|
+
return [];
|
|
21781
|
+
}
|
|
21782
|
+
const providers = await this.deps.providerStore.listProviders(tenantId);
|
|
21783
|
+
const registered = [];
|
|
21784
|
+
for (const provider of providers) {
|
|
21785
|
+
if (!provider.enabled) {
|
|
21786
|
+
continue;
|
|
21787
|
+
}
|
|
21788
|
+
const models = await this.deps.providerStore.listModels(
|
|
21789
|
+
tenantId,
|
|
21790
|
+
provider.id
|
|
21791
|
+
);
|
|
21792
|
+
registered.push(...this.syncRegistry(tenantId, provider, models));
|
|
21793
|
+
}
|
|
21794
|
+
return registered;
|
|
21795
|
+
}
|
|
20917
21796
|
/**
|
|
20918
21797
|
* Create a provider configuration. Does not run discovery.
|
|
20919
21798
|
*/
|
|
@@ -21153,7 +22032,7 @@ var ModelProviderService = class {
|
|
|
21153
22032
|
models
|
|
21154
22033
|
};
|
|
21155
22034
|
} catch (error) {
|
|
21156
|
-
if (error instanceof ModelProviderServiceError) {
|
|
22035
|
+
if (error instanceof ModelProviderServiceError && isUpstreamErrorCode(error.code)) {
|
|
21157
22036
|
return {
|
|
21158
22037
|
reachable: false,
|
|
21159
22038
|
latencyMs: Date.now() - startedAt,
|
|
@@ -21392,9 +22271,9 @@ var ModelProviderService = class {
|
|
|
21392
22271
|
*/
|
|
21393
22272
|
async assertSafeUrl(baseURL) {
|
|
21394
22273
|
try {
|
|
21395
|
-
await (0,
|
|
22274
|
+
await (0, import_core49.assertSafeUpstreamUrl)(baseURL);
|
|
21396
22275
|
} catch (error) {
|
|
21397
|
-
if (error instanceof
|
|
22276
|
+
if (error instanceof import_core49.UnsafeUpstreamUrlError) {
|
|
21398
22277
|
throw new ModelProviderServiceError(
|
|
21399
22278
|
unsafeReasonToErrorCode[error.reason],
|
|
21400
22279
|
400,
|
|
@@ -21570,6 +22449,10 @@ var ModelProviderController = class {
|
|
|
21570
22449
|
return sendError2(reply, error);
|
|
21571
22450
|
}
|
|
21572
22451
|
}
|
|
22452
|
+
/** Hydrates the runtime model registry from persisted providers (startup). */
|
|
22453
|
+
async hydrateRegistry() {
|
|
22454
|
+
return this.service.hydrateRegistry();
|
|
22455
|
+
}
|
|
21573
22456
|
/** GET /api/model-providers */
|
|
21574
22457
|
async listProviders(request, reply) {
|
|
21575
22458
|
try {
|
|
@@ -22413,8 +23296,8 @@ var RoomMessageService = class {
|
|
|
22413
23296
|
const resolved = await promise;
|
|
22414
23297
|
return this.resultForCaller(resolved, resolved.replayed);
|
|
22415
23298
|
}
|
|
22416
|
-
const
|
|
22417
|
-
return this.resultForCaller(
|
|
23299
|
+
const outcome2 = await this.createAndDispatchOutcome(actor3, normalized, room);
|
|
23300
|
+
return this.resultForCaller(outcome2, outcome2.replayed);
|
|
22418
23301
|
}
|
|
22419
23302
|
async createAndDispatchOutcome(actor3, input, room) {
|
|
22420
23303
|
const persisted = await this.persistNormalizedHumanMessage(actor3, input, room);
|
|
@@ -22463,8 +23346,8 @@ var RoomMessageService = class {
|
|
|
22463
23346
|
}
|
|
22464
23347
|
throw new RoomMessageServiceError("ROOM_DISPATCH_OVERLOADED", 429, "Room dispatch capacity is full", true);
|
|
22465
23348
|
}
|
|
22466
|
-
resultForCaller(
|
|
22467
|
-
return { message: cloneRoomMessage(
|
|
23349
|
+
resultForCaller(outcome2, replayed) {
|
|
23350
|
+
return { message: cloneRoomMessage(outcome2.message), dispatch: outcome2.dispatch.map((entry) => ({ ...entry })), replayed };
|
|
22468
23351
|
}
|
|
22469
23352
|
/** Retries an existing human message using the current roster without creating a copy. */
|
|
22470
23353
|
async retry(actor3, messageId) {
|
|
@@ -22856,7 +23739,7 @@ async function execute(reply, operation) {
|
|
|
22856
23739
|
// src/routes/cospace.ts
|
|
22857
23740
|
var import_node_crypto20 = require("crypto");
|
|
22858
23741
|
var import_zod15 = require("zod");
|
|
22859
|
-
var
|
|
23742
|
+
var import_core50 = require("@axiom-lattice/core");
|
|
22860
23743
|
var import_protocols19 = require("@axiom-lattice/protocols");
|
|
22861
23744
|
var CoSpaceAuthError = class extends Error {
|
|
22862
23745
|
constructor() {
|
|
@@ -23041,14 +23924,14 @@ function registerCoSpaceRoutes(app2, deps) {
|
|
|
23041
23924
|
}
|
|
23042
23925
|
let projectId;
|
|
23043
23926
|
if (body.type === "human") {
|
|
23044
|
-
projectId = (0,
|
|
23927
|
+
projectId = (0, import_core50.generateDirectHumanProjectId)(
|
|
23045
23928
|
actor3.tenantId,
|
|
23046
23929
|
params.workspaceId,
|
|
23047
23930
|
actor3.userId,
|
|
23048
23931
|
body.targetUserId
|
|
23049
23932
|
);
|
|
23050
23933
|
} else {
|
|
23051
|
-
projectId = (0,
|
|
23934
|
+
projectId = (0, import_core50.generateDirectBotProjectId)(
|
|
23052
23935
|
actor3.tenantId,
|
|
23053
23936
|
params.workspaceId,
|
|
23054
23937
|
actor3.userId,
|
|
@@ -23255,7 +24138,7 @@ function registerCoSpaceRoutes(app2, deps) {
|
|
|
23255
24138
|
);
|
|
23256
24139
|
const bots = [];
|
|
23257
24140
|
for (const assistant of assistants) {
|
|
23258
|
-
const directProjectId = (0,
|
|
24141
|
+
const directProjectId = (0, import_core50.generateDirectBotProjectId)(
|
|
23259
24142
|
actor3.tenantId,
|
|
23260
24143
|
params.workspaceId,
|
|
23261
24144
|
actor3.userId,
|
|
@@ -23317,7 +24200,7 @@ function registerCoSpaceRoutes(app2, deps) {
|
|
|
23317
24200
|
if (link.userId === actor3.userId) continue;
|
|
23318
24201
|
const user = await deps.userStore.getUserById(link.userId);
|
|
23319
24202
|
if (!user) continue;
|
|
23320
|
-
const directProjectId = (0,
|
|
24203
|
+
const directProjectId = (0, import_core50.generateDirectHumanProjectId)(
|
|
23321
24204
|
actor3.tenantId,
|
|
23322
24205
|
params.workspaceId,
|
|
23323
24206
|
actor3.userId,
|
|
@@ -23843,6 +24726,7 @@ function exactValues(value, required, optional = []) {
|
|
|
23843
24726
|
// src/services/collaboration/CoordinatorWakeNotifier.ts
|
|
23844
24727
|
var import_node_crypto21 = require("crypto");
|
|
23845
24728
|
var import_protocols21 = require("@axiom-lattice/protocols");
|
|
24729
|
+
init_projectTaskScope();
|
|
23846
24730
|
var SYNTHETIC_WAKE_AUTHOR = "coordinator-wake";
|
|
23847
24731
|
var CoordinatorWakeNotifier = class {
|
|
23848
24732
|
/** Creates a bounded Project Task lifecycle observer that wakes the Room Coordinator. */
|
|
@@ -23900,10 +24784,10 @@ var CoordinatorWakeNotifier = class {
|
|
|
23900
24784
|
timer = setTimeout(() => resolve4("timeout"), timeoutMs);
|
|
23901
24785
|
timer.unref?.();
|
|
23902
24786
|
});
|
|
23903
|
-
const
|
|
24787
|
+
const outcome2 = await Promise.race([work.then(() => "drained"), timeout]);
|
|
23904
24788
|
if (timer) clearTimeout(timer);
|
|
23905
24789
|
this.closed = true;
|
|
23906
|
-
if (
|
|
24790
|
+
if (outcome2 === "timeout") this.queues.clear();
|
|
23907
24791
|
}
|
|
23908
24792
|
/** Closes admission and drains accepted work. */
|
|
23909
24793
|
async dispose() {
|
|
@@ -24133,6 +25017,8 @@ function createRoomMessageRetentionJob(input) {
|
|
|
24133
25017
|
|
|
24134
25018
|
// src/services/collaboration/ProjectTaskExecutionMutex.ts
|
|
24135
25019
|
var import_protocols22 = require("@axiom-lattice/protocols");
|
|
25020
|
+
var import_core51 = require("@axiom-lattice/core");
|
|
25021
|
+
var MACHINE_LEASE_OPTIONS = { ttlMs: 6e4, acquireTimeoutMs: 9e4, retryDelayMs: 100 };
|
|
24136
25022
|
function machineKey(scope) {
|
|
24137
25023
|
const snapshot = (0, import_protocols22.snapshotExactRecord)(scope, ["tenantId", "assistantId", "projectId"]);
|
|
24138
25024
|
if (!snapshot) throw new Error("Invalid Project task machine scope");
|
|
@@ -24156,9 +25042,12 @@ var ProjectTaskExecutionMutex = class {
|
|
|
24156
25042
|
*/
|
|
24157
25043
|
async runExclusive(scope, operation, signal) {
|
|
24158
25044
|
const key = machineKey(scope);
|
|
25045
|
+
const leaseKey = `project-task-machine:${encodeURIComponent(scope.tenantId)}:${encodeURIComponent(scope.assistantId)}:${encodeURIComponent(scope.projectId)}`;
|
|
24159
25046
|
await this.acquire(key, signal);
|
|
24160
25047
|
try {
|
|
24161
|
-
|
|
25048
|
+
const store2 = (0, import_core51.getCoordinationLeaseStore)();
|
|
25049
|
+
if (!store2) return await operation();
|
|
25050
|
+
return await (0, import_core51.withLease)(store2, leaseKey, (0, import_core51.getReplicaId)(), operation, MACHINE_LEASE_OPTIONS);
|
|
24162
25051
|
} finally {
|
|
24163
25052
|
this.release(key);
|
|
24164
25053
|
}
|
|
@@ -24211,8 +25100,23 @@ var ProjectTaskExecutionMutex = class {
|
|
|
24211
25100
|
|
|
24212
25101
|
// src/services/collaboration/ProjectTaskObserver.ts
|
|
24213
25102
|
var import_node_crypto22 = require("crypto");
|
|
24214
|
-
var
|
|
25103
|
+
var import_core52 = require("@axiom-lattice/core");
|
|
24215
25104
|
var import_protocols23 = require("@axiom-lattice/protocols");
|
|
25105
|
+
|
|
25106
|
+
// src/services/collaboration/projectTaskDispatchMarker.ts
|
|
25107
|
+
var EXECUTION_REQUESTED_AT_KEY = "execution_requested_at";
|
|
25108
|
+
function hasExecutionRequest(task) {
|
|
25109
|
+
const value = task.context?.[EXECUTION_REQUESTED_AT_KEY];
|
|
25110
|
+
if (typeof value !== "string" || value.length === 0) return false;
|
|
25111
|
+
const parsed = new Date(value);
|
|
25112
|
+
return Number.isFinite(parsed.getTime()) && parsed.toISOString() === value;
|
|
25113
|
+
}
|
|
25114
|
+
function withExecutionRequest(context, nowIso) {
|
|
25115
|
+
return { ...context ?? {}, [EXECUTION_REQUESTED_AT_KEY]: nowIso };
|
|
25116
|
+
}
|
|
25117
|
+
|
|
25118
|
+
// src/services/collaboration/ProjectTaskObserver.ts
|
|
25119
|
+
init_projectTaskScope();
|
|
24216
25120
|
var SYSTEM_ACTOR2 = "system";
|
|
24217
25121
|
var TERMINAL_ACTIONS = ["completed", "failed", "interrupted", "cancelled"];
|
|
24218
25122
|
var ProjectTaskObserver = class {
|
|
@@ -24233,7 +25137,7 @@ var ProjectTaskObserver = class {
|
|
|
24233
25137
|
throw new Error(`Invalid Project task observer bound: ${name}`);
|
|
24234
25138
|
}
|
|
24235
25139
|
}
|
|
24236
|
-
this.runBridge = (0,
|
|
25140
|
+
this.runBridge = (0, import_core52.createTaskRunBridge)({ lifecycle: this.deps.lifecycle });
|
|
24237
25141
|
}
|
|
24238
25142
|
/** Fire-and-forget notifier adapter that never waits for observer work or machine acquisition. */
|
|
24239
25143
|
async listener(event) {
|
|
@@ -24412,11 +25316,11 @@ var ProjectTaskObserver = class {
|
|
|
24412
25316
|
try {
|
|
24413
25317
|
await this.requireActiveOwner(task);
|
|
24414
25318
|
} catch (error) {
|
|
24415
|
-
await this.
|
|
25319
|
+
await this.convergeFailed(task, `No active executor: ${errorMessage3(error)}`);
|
|
24416
25320
|
return;
|
|
24417
25321
|
}
|
|
24418
25322
|
}
|
|
24419
|
-
if (intent === "dispatch" && await this.isReady(task) && !signal?.aborted && !this.disposed) {
|
|
25323
|
+
if ((intent === "dispatch" || hasExecutionRequest(task)) && await this.isReady(task) && !signal?.aborted && !this.disposed) {
|
|
24420
25324
|
await this.runStart(task, signal);
|
|
24421
25325
|
}
|
|
24422
25326
|
return;
|
|
@@ -24511,7 +25415,7 @@ var ProjectTaskObserver = class {
|
|
|
24511
25415
|
const classification = await this.deps.execution.classifyRecovery(current, ensured.thread);
|
|
24512
25416
|
if (signal?.aborted || this.disposed) return;
|
|
24513
25417
|
if (classification.kind === "invalid") {
|
|
24514
|
-
await this.
|
|
25418
|
+
await this.convergeFailed(
|
|
24515
25419
|
current,
|
|
24516
25420
|
`Task execution state is not recoverable: ${classification.reason}`
|
|
24517
25421
|
);
|
|
@@ -24532,40 +25436,40 @@ var ProjectTaskObserver = class {
|
|
|
24532
25436
|
}
|
|
24533
25437
|
}, signal);
|
|
24534
25438
|
}
|
|
24535
|
-
async mapOutcome(
|
|
24536
|
-
if (
|
|
24537
|
-
const current = snapshotTaskItem(await this.deps.tasks.getById(
|
|
24538
|
-
if (!current || current.ownerId !==
|
|
25439
|
+
async mapOutcome(outcome2) {
|
|
25440
|
+
if (outcome2.kind === "aborted" || outcome2.kind === "deferred") return;
|
|
25441
|
+
const current = snapshotTaskItem(await this.deps.tasks.getById(outcome2.task.tenantId, outcome2.task.id));
|
|
25442
|
+
if (!current || current.ownerId !== outcome2.thread.assistantId || current.context?.thread_id !== outcome2.thread.id) return;
|
|
24539
25443
|
if (isTerminal(current.status) || current.status === "review") return;
|
|
24540
|
-
if (
|
|
25444
|
+
if (outcome2.kind === "completed") {
|
|
24541
25445
|
const result2 = await this.runBridge.settleRun({
|
|
24542
25446
|
tenantId: current.tenantId,
|
|
24543
25447
|
task: current,
|
|
24544
25448
|
actor: SYSTEM_ACTOR2,
|
|
24545
|
-
threadId:
|
|
25449
|
+
threadId: outcome2.thread.id,
|
|
24546
25450
|
outcome: { kind: "completed" }
|
|
24547
25451
|
});
|
|
24548
25452
|
await this.checkLifecycle(current, "outcome-completed", result2);
|
|
24549
25453
|
return;
|
|
24550
25454
|
}
|
|
24551
|
-
if (
|
|
25455
|
+
if (outcome2.kind === "cancelled") {
|
|
24552
25456
|
const result2 = await this.runBridge.settleRun({
|
|
24553
25457
|
tenantId: current.tenantId,
|
|
24554
25458
|
task: current,
|
|
24555
25459
|
actor: SYSTEM_ACTOR2,
|
|
24556
|
-
threadId:
|
|
25460
|
+
threadId: outcome2.thread.id,
|
|
24557
25461
|
outcome: { kind: "cancelled" }
|
|
24558
25462
|
});
|
|
24559
25463
|
await this.checkLifecycle(current, "outcome-cancelled", result2);
|
|
24560
25464
|
return;
|
|
24561
25465
|
}
|
|
24562
|
-
if (
|
|
24563
|
-
if (
|
|
25466
|
+
if (outcome2.kind === "failed" && outcome2.lifecycleHandled) return;
|
|
25467
|
+
if (outcome2.kind === "interrupted") {
|
|
24564
25468
|
const result2 = await this.runBridge.settleRun({
|
|
24565
25469
|
tenantId: current.tenantId,
|
|
24566
25470
|
task: current,
|
|
24567
25471
|
actor: SYSTEM_ACTOR2,
|
|
24568
|
-
threadId:
|
|
25472
|
+
threadId: outcome2.thread.id,
|
|
24569
25473
|
outcome: { kind: "interrupted" }
|
|
24570
25474
|
});
|
|
24571
25475
|
await this.checkLifecycle(current, "outcome-interrupted", result2);
|
|
@@ -24575,10 +25479,10 @@ var ProjectTaskObserver = class {
|
|
|
24575
25479
|
tenantId: current.tenantId,
|
|
24576
25480
|
task: current,
|
|
24577
25481
|
actor: SYSTEM_ACTOR2,
|
|
24578
|
-
threadId:
|
|
24579
|
-
outcome: { kind: "failed", lifecycleHandled: false, error:
|
|
25482
|
+
threadId: outcome2.thread.id,
|
|
25483
|
+
outcome: { kind: "failed", lifecycleHandled: false, error: outcome2.error }
|
|
24580
25484
|
});
|
|
24581
|
-
await this.checkLifecycle(current, `outcome-${
|
|
25485
|
+
await this.checkLifecycle(current, `outcome-${outcome2.cause}`, result);
|
|
24582
25486
|
}
|
|
24583
25487
|
async collectDependentIds(task) {
|
|
24584
25488
|
const rows = /* @__PURE__ */ new Map();
|
|
@@ -24778,25 +25682,26 @@ var ProjectTaskObserver = class {
|
|
|
24778
25682
|
}
|
|
24779
25683
|
}
|
|
24780
25684
|
/**
|
|
24781
|
-
* Converges
|
|
25685
|
+
* Converges a mechanically unexecutable task to a durable failure.
|
|
24782
25686
|
*
|
|
24783
25687
|
* @param task Exact task snapshot that cannot make progress through automation.
|
|
24784
|
-
* @param
|
|
25688
|
+
* @param failureReason Human-readable reason recorded with the failure.
|
|
24785
25689
|
* @remarks Never leaves a task silently pending behind a warning; an `in_progress`
|
|
24786
25690
|
* task with no dispatched queue rows is intentionally left untouched by recovery.
|
|
24787
|
-
*
|
|
25691
|
+
* A no-executor/unrecoverable state is a mechanical failure (`failed`), not HITL
|
|
25692
|
+
* (ADR-143); `failed` remains retryable.
|
|
24788
25693
|
*/
|
|
24789
|
-
async
|
|
25694
|
+
async convergeFailed(task, failureReason) {
|
|
24790
25695
|
if (this.disposed) return;
|
|
24791
25696
|
try {
|
|
24792
25697
|
const result = await this.runBridge.settleRun({
|
|
24793
25698
|
tenantId: task.tenantId,
|
|
24794
25699
|
task,
|
|
24795
25700
|
actor: SYSTEM_ACTOR2,
|
|
24796
|
-
outcome: { kind: "
|
|
25701
|
+
outcome: { kind: "failed", lifecycleHandled: false, error: failureReason }
|
|
24797
25702
|
});
|
|
24798
25703
|
if (!result.success && result.code !== "TASK_STATUS_CONFLICT") {
|
|
24799
|
-
await this.safeWarning(task, "converge", `${result.code ?? "LIFECYCLE_REJECTED"}: ${result.error ??
|
|
25704
|
+
await this.safeWarning(task, "converge", `${result.code ?? "LIFECYCLE_REJECTED"}: ${result.error ?? failureReason}`);
|
|
24800
25705
|
}
|
|
24801
25706
|
} catch (error) {
|
|
24802
25707
|
await this.safeWarning(task, "converge", error);
|
|
@@ -25074,6 +25979,7 @@ function combineSignals(left, right) {
|
|
|
25074
25979
|
// src/services/collaboration/RoomProjectionService.ts
|
|
25075
25980
|
var import_node_crypto23 = require("crypto");
|
|
25076
25981
|
var import_protocols24 = require("@axiom-lattice/protocols");
|
|
25982
|
+
init_projectTaskScope();
|
|
25077
25983
|
var ROOM_PROJECTABLE_ACTIONS = [
|
|
25078
25984
|
"interrupted",
|
|
25079
25985
|
"failed",
|
|
@@ -25443,8 +26349,11 @@ function isRecord3(value) {
|
|
|
25443
26349
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
25444
26350
|
}
|
|
25445
26351
|
|
|
26352
|
+
// src/routes/index.ts
|
|
26353
|
+
init_projectTaskScope();
|
|
26354
|
+
|
|
25446
26355
|
// src/services/collaboration/ProjectRoomRealtimeRuntime.ts
|
|
25447
|
-
var
|
|
26356
|
+
var import_core53 = require("@axiom-lattice/core");
|
|
25448
26357
|
|
|
25449
26358
|
// src/services/collaboration/ProjectRoomEventBroker.ts
|
|
25450
26359
|
var import_node_crypto24 = require("crypto");
|
|
@@ -25454,6 +26363,7 @@ var DEFAULT_MAX_EVENT_AGE_MS = 10 * 60 * 1e3;
|
|
|
25454
26363
|
var DEFAULT_MAX_ROOMS = 1e3;
|
|
25455
26364
|
var DEFAULT_MAX_GLOBAL_EVENTS = 1e5;
|
|
25456
26365
|
var DEFAULT_MAX_GLOBAL_BYTES = 64 * 1024 * 1024;
|
|
26366
|
+
var DEFAULT_SOURCE_KEY_LIMIT = 2e3;
|
|
25457
26367
|
var UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/;
|
|
25458
26368
|
var ProjectRoomBrokerResourceCapacityError = class extends Error {
|
|
25459
26369
|
constructor(resource) {
|
|
@@ -25467,6 +26377,7 @@ var ProjectRoomEventBroker = class {
|
|
|
25467
26377
|
constructor(options = {}) {
|
|
25468
26378
|
this.rooms = /* @__PURE__ */ new Map();
|
|
25469
26379
|
this.sequenceScopes = /* @__PURE__ */ new Map();
|
|
26380
|
+
this.seenSourceKeys = /* @__PURE__ */ new Map();
|
|
25470
26381
|
this.eventCount = 0;
|
|
25471
26382
|
this.byteCount = 0;
|
|
25472
26383
|
this.subscriberCount = 0;
|
|
@@ -25494,6 +26405,10 @@ var ProjectRoomEventBroker = class {
|
|
|
25494
26405
|
options.maxGlobalBytes ?? DEFAULT_MAX_GLOBAL_BYTES,
|
|
25495
26406
|
"maxGlobalBytes"
|
|
25496
26407
|
);
|
|
26408
|
+
this.sourceKeyLimit = positiveSafeInteger(
|
|
26409
|
+
options.sourceKeyLimit ?? DEFAULT_SOURCE_KEY_LIMIT,
|
|
26410
|
+
"sourceKeyLimit"
|
|
26411
|
+
);
|
|
25497
26412
|
this.sequence = nonnegativeSafeInteger(options.initialSequence ?? 0, "initialSequence");
|
|
25498
26413
|
this.log = options.log ?? { warn: () => void 0 };
|
|
25499
26414
|
}
|
|
@@ -25505,8 +26420,22 @@ var ProjectRoomEventBroker = class {
|
|
|
25505
26420
|
get retainedBytes() {
|
|
25506
26421
|
return this.byteCount;
|
|
25507
26422
|
}
|
|
25508
|
-
/**
|
|
25509
|
-
|
|
26423
|
+
/**
|
|
26424
|
+
* Installs (or clears) a hook invoked after a locally published event is stored
|
|
26425
|
+
* and queued to local subscribers. Used to mirror events to other replicas via
|
|
26426
|
+
* a shared transport. Best-effort: a throwing hook never affects `publish`.
|
|
26427
|
+
*/
|
|
26428
|
+
setBroadcastHook(hook) {
|
|
26429
|
+
this.broadcast = hook;
|
|
26430
|
+
}
|
|
26431
|
+
/**
|
|
26432
|
+
* Atomically stores an immutable event before queueing detached listener callbacks.
|
|
26433
|
+
*
|
|
26434
|
+
* @param sourceKey Optional caller-owned fact key; when present it is retained
|
|
26435
|
+
* for bounded cross-replica duplicate suppression so a later foreign copy of the
|
|
26436
|
+
* same fact (or a local publish) is dropped by {@link ingestForeignEvent}.
|
|
26437
|
+
*/
|
|
26438
|
+
publish(scope, draft, sourceKey) {
|
|
25510
26439
|
this.assertOpen();
|
|
25511
26440
|
const canonicalScope = snapshotScope(scope);
|
|
25512
26441
|
const key = scopeKey2(canonicalScope);
|
|
@@ -25541,9 +26470,52 @@ var ProjectRoomEventBroker = class {
|
|
|
25541
26470
|
this.sequence = nextSequence;
|
|
25542
26471
|
this.eventCount += 1;
|
|
25543
26472
|
this.byteCount += bytes;
|
|
26473
|
+
if (sourceKey !== void 0) this.rememberSourceKey(sourceKey);
|
|
25544
26474
|
for (const subscription of [...room.subscriptions]) this.queueCallback(subscription, serialized);
|
|
26475
|
+
if (this.broadcast) {
|
|
26476
|
+
try {
|
|
26477
|
+
this.broadcast(canonicalScope, serialized, sourceKey);
|
|
26478
|
+
} catch {
|
|
26479
|
+
}
|
|
26480
|
+
}
|
|
25545
26481
|
return parseScopedEvent(serialized);
|
|
25546
26482
|
}
|
|
26483
|
+
/**
|
|
26484
|
+
* Delivers one event published by ANOTHER replica to this process's local
|
|
26485
|
+
* subscribers for its room, without adding it to the local replay ring or
|
|
26486
|
+
* consuming a local sequence (its id carries the origin replica's epoch).
|
|
26487
|
+
*
|
|
26488
|
+
* @param serializedEvent A serialized scoped business event produced by a peer.
|
|
26489
|
+
* @param sourceKey Optional caller-owned fact key shared by every replica's copy
|
|
26490
|
+
* of the same committed fact. When it was already seen (locally published or
|
|
26491
|
+
* ingested from a peer) the event is dropped to avoid N× duplicate delivery.
|
|
26492
|
+
* @returns True when it was queued to at least one local subscription.
|
|
26493
|
+
* @remarks Source-key deduplication is process-local and bounded, so it caps
|
|
26494
|
+
* duplicate fan-out within the retention window without replacing REST, which
|
|
26495
|
+
* remains the authority. A malformed payload or a room with no local
|
|
26496
|
+
* subscribers is ignored.
|
|
26497
|
+
*/
|
|
26498
|
+
ingestForeignEvent(serializedEvent, sourceKey) {
|
|
26499
|
+
this.assertOpen();
|
|
26500
|
+
if (sourceKey !== void 0 && this.seenSourceKeys.has(sourceKey)) return false;
|
|
26501
|
+
let key;
|
|
26502
|
+
try {
|
|
26503
|
+
const event = parseScopedEvent(serializedEvent);
|
|
26504
|
+
key = scopeKey2(snapshotScope(event.scope));
|
|
26505
|
+
} catch {
|
|
26506
|
+
return false;
|
|
26507
|
+
}
|
|
26508
|
+
if (sourceKey !== void 0) this.rememberSourceKey(sourceKey);
|
|
26509
|
+
const room = this.rooms.get(key);
|
|
26510
|
+
if (!room || room.subscriptions.size === 0) return false;
|
|
26511
|
+
this.touch(room);
|
|
26512
|
+
let queued = false;
|
|
26513
|
+
for (const subscription of [...room.subscriptions]) {
|
|
26514
|
+
this.queueCallback(subscription, serializedEvent);
|
|
26515
|
+
queued = true;
|
|
26516
|
+
}
|
|
26517
|
+
return queued;
|
|
26518
|
+
}
|
|
25547
26519
|
/** Atomically resolves replay and registers a distinct subscription for live events. */
|
|
25548
26520
|
subscribe(scope, afterEventId, listener) {
|
|
25549
26521
|
this.assertOpen();
|
|
@@ -25583,6 +26555,7 @@ var ProjectRoomEventBroker = class {
|
|
|
25583
26555
|
}
|
|
25584
26556
|
this.rooms.clear();
|
|
25585
26557
|
this.sequenceScopes.clear();
|
|
26558
|
+
this.seenSourceKeys.clear();
|
|
25586
26559
|
this.eventCount = 0;
|
|
25587
26560
|
this.byteCount = 0;
|
|
25588
26561
|
this.subscriberCount = 0;
|
|
@@ -25717,6 +26690,14 @@ var ProjectRoomEventBroker = class {
|
|
|
25717
26690
|
this.usageClock += 1;
|
|
25718
26691
|
room.lastUsed = this.usageClock;
|
|
25719
26692
|
}
|
|
26693
|
+
rememberSourceKey(key) {
|
|
26694
|
+
this.seenSourceKeys.set(key, true);
|
|
26695
|
+
while (this.seenSourceKeys.size > this.sourceKeyLimit) {
|
|
26696
|
+
const oldest = this.seenSourceKeys.keys().next().value;
|
|
26697
|
+
if (oldest === void 0) break;
|
|
26698
|
+
this.seenSourceKeys.delete(oldest);
|
|
26699
|
+
}
|
|
26700
|
+
}
|
|
25720
26701
|
};
|
|
25721
26702
|
function positiveSafeInteger(value, name) {
|
|
25722
26703
|
if (!Number.isSafeInteger(value) || value <= 0) throw new RangeError(`${name} must be a positive safe integer`);
|
|
@@ -25908,7 +26889,7 @@ var BrokerProjectRoomRealtimePublisher = class {
|
|
|
25908
26889
|
if (!event) throw new Error("Invalid Project Room realtime projection");
|
|
25909
26890
|
const dedupeKey = (0, import_node_crypto25.createHash)("sha256").update(JSON.stringify([type, event.scope.tenantId, event.scope.projectId, event.scope.roomId, event.sourceKey])).digest("hex");
|
|
25910
26891
|
if (this.sourceKeys.has(dedupeKey)) return;
|
|
25911
|
-
this.deps.broker.publish(event.scope, event.draft);
|
|
26892
|
+
this.deps.broker.publish(event.scope, event.draft, event.sourceKey);
|
|
25912
26893
|
this.sourceKeys.set(dedupeKey, true);
|
|
25913
26894
|
while (this.sourceKeys.size > this.dedupeLimit) {
|
|
25914
26895
|
const oldest = this.sourceKeys.keys().next().value;
|
|
@@ -25961,6 +26942,7 @@ function safeErrorCode(error) {
|
|
|
25961
26942
|
|
|
25962
26943
|
// src/services/collaboration/ProjectRoomTaskEventSubscriber.ts
|
|
25963
26944
|
var import_protocols27 = require("@axiom-lattice/protocols");
|
|
26945
|
+
init_projectTaskScope();
|
|
25964
26946
|
var ProjectRoomTaskEventSubscriber = class {
|
|
25965
26947
|
/** Creates a bounded Project task lifecycle observer. */
|
|
25966
26948
|
constructor(deps) {
|
|
@@ -26015,10 +26997,10 @@ var ProjectRoomTaskEventSubscriber = class {
|
|
|
26015
26997
|
timer = setTimeout(() => resolve4("timeout"), timeoutMs);
|
|
26016
26998
|
timer.unref?.();
|
|
26017
26999
|
});
|
|
26018
|
-
const
|
|
27000
|
+
const outcome2 = await Promise.race([work.then(() => "drained"), timeout]);
|
|
26019
27001
|
if (timer) clearTimeout(timer);
|
|
26020
27002
|
this.closed = true;
|
|
26021
|
-
if (
|
|
27003
|
+
if (outcome2 === "timeout") this.queues.clear();
|
|
26022
27004
|
}
|
|
26023
27005
|
/** Closes admission and drains accepted work. */
|
|
26024
27006
|
async dispose() {
|
|
@@ -26146,7 +27128,7 @@ function createProjectRoomRealtimeRuntime(deps) {
|
|
|
26146
27128
|
broker,
|
|
26147
27129
|
publisher,
|
|
26148
27130
|
subscriber,
|
|
26149
|
-
subscribe: (listener) =>
|
|
27131
|
+
subscribe: (listener) => import_core53.taskLifecycleNotifier.subscribe(listener),
|
|
26150
27132
|
log: deps.log,
|
|
26151
27133
|
shutdownTimeoutMs: deps.shutdownTimeoutMs
|
|
26152
27134
|
});
|
|
@@ -26884,35 +27866,35 @@ function hookErrorMessage(error) {
|
|
|
26884
27866
|
function wrapReassignmentThreadError(error) {
|
|
26885
27867
|
if (error instanceof ProjectTaskThreadError) {
|
|
26886
27868
|
if (error.code === "PROJECT_TASK_THREAD_SCOPE_INVALID") {
|
|
26887
|
-
return new
|
|
27869
|
+
return new import_core54.ManagedTaskStartError("PROJECT_TASK_CONTEXT_INVALID", error.message, {
|
|
26888
27870
|
hint: "Project task, room, or roster scope changed; re-read the task and retry."
|
|
26889
27871
|
});
|
|
26890
27872
|
}
|
|
26891
27873
|
if (error.code === "PROJECT_TASK_THREAD_OWNER_INVALID") {
|
|
26892
|
-
return new
|
|
27874
|
+
return new import_core54.ManagedTaskStartError("TASK_REASSIGN_NO_CHANGE", error.message, {
|
|
26893
27875
|
hint: "The target already owns this task; re-read before dispatching."
|
|
26894
27876
|
});
|
|
26895
27877
|
}
|
|
26896
|
-
return new
|
|
27878
|
+
return new import_core54.ManagedTaskStartError("TASK_THREAD_CONFLICT", error.message, {
|
|
26897
27879
|
hint: "Task Thread changed concurrently; re-read the task and retry."
|
|
26898
27880
|
});
|
|
26899
27881
|
}
|
|
26900
|
-
return new
|
|
27882
|
+
return new import_core54.ManagedTaskStartError("TASK_EXECUTION_ENQUEUE_FAILED", hookErrorMessage(error), {
|
|
26901
27883
|
hint: "Re-read the task and retry the dispatch."
|
|
26902
27884
|
});
|
|
26903
27885
|
}
|
|
26904
27886
|
function wrapReassignmentAuthorizationError(error) {
|
|
26905
|
-
if (error instanceof
|
|
27887
|
+
if (error instanceof import_core54.ProjectTaskOwnerPolicyError) {
|
|
26906
27888
|
if (error.code === "PROJECT_TASK_CALLER_INACTIVE") {
|
|
26907
|
-
return new
|
|
27889
|
+
return new import_core54.ManagedTaskStartError("PROJECT_TASK_CALLER_INACTIVE", error.message, {
|
|
26908
27890
|
hint: "Dispatch from an active Project Room member bot."
|
|
26909
27891
|
});
|
|
26910
27892
|
}
|
|
26911
|
-
return new
|
|
27893
|
+
return new import_core54.ManagedTaskStartError("PROJECT_TASK_OWNER_INACTIVE", error.message, {
|
|
26912
27894
|
hint: "Dispatch to an active bot in this Project's roster."
|
|
26913
27895
|
});
|
|
26914
27896
|
}
|
|
26915
|
-
return new
|
|
27897
|
+
return new import_core54.ManagedTaskStartError("PROJECT_TASK_CONTEXT_INVALID", hookErrorMessage(error), {
|
|
26916
27898
|
hint: "Re-read the task and roster, then retry the dispatch."
|
|
26917
27899
|
});
|
|
26918
27900
|
}
|
|
@@ -26941,43 +27923,43 @@ async function transferGovernedDispatchOwner(task, options, deps) {
|
|
|
26941
27923
|
const agentId = options?.agentId;
|
|
26942
27924
|
if (!agentId || agentId === task.ownerId) return void 0;
|
|
26943
27925
|
if (!task.workspaceId || !task.projectId) {
|
|
26944
|
-
throw new
|
|
27926
|
+
throw new import_core54.ManagedTaskStartError("PROJECT_TASK_CONTEXT_INVALID", "Task is not governed by a Project lifecycle.", {
|
|
26945
27927
|
hint: "Dispatch governed tasks from a trusted Project run; ordinary tasks execute immediately."
|
|
26946
27928
|
});
|
|
26947
27929
|
}
|
|
26948
27930
|
return deps.mutex.runExclusive({ tenantId: task.tenantId, projectId: task.projectId }, async () => {
|
|
26949
27931
|
const current = await deps.tasks.getById(task.tenantId, task.id);
|
|
26950
27932
|
if (!current || !isProjectLifecycleTask(current) || current.workspaceId !== task.workspaceId || current.projectId !== task.projectId) {
|
|
26951
|
-
throw new
|
|
27933
|
+
throw new import_core54.ManagedTaskStartError("PROJECT_TASK_CONTEXT_INVALID", "Task is no longer a Project lifecycle task.", {
|
|
26952
27934
|
hint: "Re-read the task and confirm it still belongs to this Project before dispatching."
|
|
26953
27935
|
});
|
|
26954
27936
|
}
|
|
26955
27937
|
if (current.ownerType !== "agent") {
|
|
26956
|
-
throw new
|
|
27938
|
+
throw new import_core54.ManagedTaskStartError("AGENT_TASK_REQUIRED", "Project task owner must be an Agent.", {
|
|
26957
27939
|
hint: "Assign the task to an Agent before dispatching."
|
|
26958
27940
|
});
|
|
26959
27941
|
}
|
|
26960
27942
|
if (current.status !== "pending") {
|
|
26961
|
-
throw new
|
|
27943
|
+
throw new import_core54.ManagedTaskStartError("TASK_NOT_DISPATCHABLE", "Only a `pending` Project task can be dispatched.", {
|
|
26962
27944
|
hint: `This task is '${current.status}'. Resolve it or create a new task before dispatching.`
|
|
26963
27945
|
});
|
|
26964
27946
|
}
|
|
26965
27947
|
if (agentId === current.ownerId) return current;
|
|
26966
27948
|
const room = await deps.rooms.getMainRoom(current.tenantId, current.projectId);
|
|
26967
27949
|
if (!room || room.tenantId !== current.tenantId || room.workspaceId !== current.workspaceId || room.projectId !== current.projectId || room.type !== "main") {
|
|
26968
|
-
throw new
|
|
27950
|
+
throw new import_core54.ManagedTaskStartError("PROJECT_TASK_CONTEXT_INVALID", "Project main room is unavailable.", {
|
|
26969
27951
|
hint: "Open or repair the Project Room before dispatching."
|
|
26970
27952
|
});
|
|
26971
27953
|
}
|
|
26972
27954
|
const target = await deps.botMemberships.findByAssistant(current.tenantId, current.projectId, agentId);
|
|
26973
27955
|
if (!target || target.status !== "active" || target.tenantId !== current.tenantId || target.workspaceId !== current.workspaceId || target.projectId !== current.projectId || target.assistantId !== agentId || target.roomId !== room.id) {
|
|
26974
|
-
throw new
|
|
27956
|
+
throw new import_core54.ManagedTaskStartError("PROJECT_TASK_OWNER_INACTIVE", "Target Project task owner is not active in the exact roster.", {
|
|
26975
27957
|
hint: "Dispatch to an active bot in this Project's roster."
|
|
26976
27958
|
});
|
|
26977
27959
|
}
|
|
26978
27960
|
const caller = options?.callerMembershipId ? await deps.botMemberships.findById(current.tenantId, options.callerMembershipId) : null;
|
|
26979
27961
|
if (!caller || !options?.callerAssistantId || caller.id !== options.callerMembershipId || caller.assistantId !== options.callerAssistantId || caller.status !== "active" || caller.tenantId !== current.tenantId || caller.workspaceId !== current.workspaceId || caller.projectId !== current.projectId || caller.roomId !== room.id) {
|
|
26980
|
-
throw new
|
|
27962
|
+
throw new import_core54.ManagedTaskStartError("PROJECT_TASK_CALLER_INACTIVE", "Current Project task caller is not active in the exact roster.", {
|
|
26981
27963
|
hint: "Dispatch from an active Project Room member bot."
|
|
26982
27964
|
});
|
|
26983
27965
|
}
|
|
@@ -27012,7 +27994,7 @@ async function transferGovernedDispatchOwner(task, options, deps) {
|
|
|
27012
27994
|
actor: `agent:${caller.assistantId}`
|
|
27013
27995
|
});
|
|
27014
27996
|
if (!result.success) {
|
|
27015
|
-
throw new
|
|
27997
|
+
throw new import_core54.ManagedTaskStartError(result.code, result.error, {
|
|
27016
27998
|
hint: result.hint ?? reassignmentFailureHint(result.code),
|
|
27017
27999
|
...result.retryable !== void 0 ? { retryable: result.retryable } : {}
|
|
27018
28000
|
});
|
|
@@ -27021,19 +28003,19 @@ async function transferGovernedDispatchOwner(task, options, deps) {
|
|
|
27021
28003
|
});
|
|
27022
28004
|
}
|
|
27023
28005
|
var registerLatticeRoutes = (app2, channelDeps, options = {}) => {
|
|
27024
|
-
const webAppStore = (0,
|
|
27025
|
-
const assistantStore = (0,
|
|
27026
|
-
const projectStore = (0,
|
|
27027
|
-
const projectMembershipStore = (0,
|
|
27028
|
-
const userTenantLinkStore = (0,
|
|
27029
|
-
const projectRoomStore = (0,
|
|
27030
|
-
const projectBotMembershipStore = (0,
|
|
27031
|
-
const projectRoomMessageStore = (0,
|
|
27032
|
-
const projectRoomReadStateStore = (0,
|
|
27033
|
-
const userPushSubscriptionStore = (0,
|
|
27034
|
-
const threadStore = (0,
|
|
27035
|
-
const taskStore = (0,
|
|
27036
|
-
const taskWorkItemStore = (0,
|
|
28006
|
+
const webAppStore = (0, import_core54.getStoreLattice)("default", "agentWebApp").store;
|
|
28007
|
+
const assistantStore = (0, import_core54.getStoreLattice)("default", "assistant").store;
|
|
28008
|
+
const projectStore = (0, import_core54.getStoreLattice)("default", "project").store;
|
|
28009
|
+
const projectMembershipStore = (0, import_core54.getStoreLattice)("default", "projectMembership").store;
|
|
28010
|
+
const userTenantLinkStore = (0, import_core54.getStoreLattice)("default", "userTenantLink").store;
|
|
28011
|
+
const projectRoomStore = (0, import_core54.getStoreLattice)("default", "projectRoom").store;
|
|
28012
|
+
const projectBotMembershipStore = (0, import_core54.getStoreLattice)("default", "projectBotMembership").store;
|
|
28013
|
+
const projectRoomMessageStore = (0, import_core54.getStoreLattice)("default", "projectRoomMessage").store;
|
|
28014
|
+
const projectRoomReadStateStore = (0, import_core54.getStoreLattice)("default", "projectRoomReadState").store;
|
|
28015
|
+
const userPushSubscriptionStore = (0, import_core54.getStoreLattice)("default", "userPushSubscription").store;
|
|
28016
|
+
const threadStore = (0, import_core54.getStoreLattice)("default", "thread").store;
|
|
28017
|
+
const taskStore = (0, import_core54.getStoreLattice)("default", "task").store;
|
|
28018
|
+
const taskWorkItemStore = (0, import_core54.getStoreLattice)("default", "taskWorkItem").store;
|
|
27037
28019
|
const projectTaskEnabled = options.projectTaskEnabled ?? process.env.AXIOM_PROJECT_TASK_EXECUTION_ENABLED !== "false";
|
|
27038
28020
|
const accessService = new ProjectAccessService({ projectStore, membershipStore: projectMembershipStore, userTenantLinkStore });
|
|
27039
28021
|
const realtimeMode = resolveProjectRoomRealtimeMode();
|
|
@@ -27099,7 +28081,7 @@ var registerLatticeRoutes = (app2, channelDeps, options = {}) => {
|
|
|
27099
28081
|
updateAssistant: assistantStore.updateAssistant.bind(assistantStore)
|
|
27100
28082
|
});
|
|
27101
28083
|
const resolveCoordinatorMentionName = async (tenantId) => {
|
|
27102
|
-
const tenant2 = await (0,
|
|
28084
|
+
const tenant2 = await (0, import_core54.getStoreLattice)("default", "tenant").store.getTenantById(tenantId);
|
|
27103
28085
|
const value = tenant2?.metadata?.coordinatorMentionName;
|
|
27104
28086
|
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
27105
28087
|
};
|
|
@@ -27126,7 +28108,7 @@ var registerLatticeRoutes = (app2, channelDeps, options = {}) => {
|
|
|
27126
28108
|
return membership !== null && membership.projectId === projectId ? membership : null;
|
|
27127
28109
|
},
|
|
27128
28110
|
getThreadStatus: async ({ tenantId, assistantId, threadId, workspaceId, projectId }) => {
|
|
27129
|
-
const agent =
|
|
28111
|
+
const agent = import_core54.agentInstanceManager.getAgent({
|
|
27130
28112
|
tenant_id: tenantId,
|
|
27131
28113
|
assistant_id: assistantId,
|
|
27132
28114
|
thread_id: threadId,
|
|
@@ -27135,9 +28117,9 @@ var registerLatticeRoutes = (app2, channelDeps, options = {}) => {
|
|
|
27135
28117
|
});
|
|
27136
28118
|
return String(await agent.getRunStatus());
|
|
27137
28119
|
},
|
|
27138
|
-
dispatcher: (0,
|
|
28120
|
+
dispatcher: (0, import_core54.createTrustedAgentMessageDispatcher)((scope) => import_core54.agentInstanceManager.getAgent(scope))
|
|
27139
28121
|
});
|
|
27140
|
-
const membershipService = new ProjectMembershipService({ membershipStore: projectMembershipStore, userTenantLinkStore, accessService, projectMutationMutex:
|
|
28122
|
+
const membershipService = new ProjectMembershipService({ membershipStore: projectMembershipStore, userTenantLinkStore, accessService, projectMutationMutex: import_core54.projectMutationMutex, roomStore: projectRoomStore, realtime, onRealtimeFailure: realtime && channelDeps?.warn ? ({ code, membershipId }) => channelDeps.warn?.("project-room:membership-realtime-failed", { code, membershipId }) : void 0 });
|
|
27141
28123
|
const rosterService = new ProjectRosterService({
|
|
27142
28124
|
accessService,
|
|
27143
28125
|
roomService,
|
|
@@ -27148,7 +28130,7 @@ var registerLatticeRoutes = (app2, channelDeps, options = {}) => {
|
|
|
27148
28130
|
assistantStore,
|
|
27149
28131
|
taskStore,
|
|
27150
28132
|
bindingLifecycle,
|
|
27151
|
-
projectMutationMutex:
|
|
28133
|
+
projectMutationMutex: import_core54.projectMutationMutex,
|
|
27152
28134
|
realtime,
|
|
27153
28135
|
onRealtimeFailure: realtime && channelDeps?.warn ? ({ code, membershipId }) => channelDeps.warn?.("project-room:roster-realtime-failed", { code, membershipId }) : void 0
|
|
27154
28136
|
});
|
|
@@ -27204,9 +28186,9 @@ var registerLatticeRoutes = (app2, channelDeps, options = {}) => {
|
|
|
27204
28186
|
}
|
|
27205
28187
|
if (projectTaskComposition) app2.addHook("onClose", async () => projectTaskComposition.lease.release());
|
|
27206
28188
|
const taskThreadService = projectTaskComposition?.lease.runtime.threads ?? new ProjectTaskThreadService({ threads: threadStore, idFactory: import_node_crypto26.randomUUID });
|
|
27207
|
-
const taskLifecycle = projectTaskComposition?.lease.runtime.lifecycle ?? (0,
|
|
27208
|
-
const reassignmentAuthorizer = (0,
|
|
27209
|
-
new
|
|
28189
|
+
const taskLifecycle = projectTaskComposition?.lease.runtime.lifecycle ?? (0, import_core54.createTaskLifecycleService)({ taskStore, workItemStore: taskWorkItemStore });
|
|
28190
|
+
const reassignmentAuthorizer = (0, import_core54.createProjectTaskReassignmentAuthorizer)(
|
|
28191
|
+
new import_core54.ProjectTaskOwnerPolicy(projectBotMembershipStore),
|
|
27210
28192
|
(input) => validateReassignmentThread(threadStore, input)
|
|
27211
28193
|
);
|
|
27212
28194
|
const taskCommandService = new TaskCommandService({
|
|
@@ -27215,7 +28197,7 @@ var registerLatticeRoutes = (app2, channelDeps, options = {}) => {
|
|
|
27215
28197
|
lifecycle: taskLifecycle,
|
|
27216
28198
|
execution: projectTaskComposition?.lease.runtime.execution,
|
|
27217
28199
|
threads: taskThreadService,
|
|
27218
|
-
agents: { getAgent: (params) =>
|
|
28200
|
+
agents: { getAgent: (params) => import_core54.agentInstanceManager.getAgent(params) },
|
|
27219
28201
|
taskScope: (task) => resolveCommandTaskScope(task, {
|
|
27220
28202
|
rooms: projectRoomStore,
|
|
27221
28203
|
bots: projectBotMembershipStore,
|
|
@@ -27253,7 +28235,7 @@ var registerLatticeRoutes = (app2, channelDeps, options = {}) => {
|
|
|
27253
28235
|
readStateService,
|
|
27254
28236
|
interruptService: roomInterruptService,
|
|
27255
28237
|
userDirectory: {
|
|
27256
|
-
getUserById: (id3) => (0,
|
|
28238
|
+
getUserById: (id3) => (0, import_core54.getStoreLattice)("default", "user").store.getUserById(id3).then((u) => u ? { name: u.name } : null)
|
|
27257
28239
|
}
|
|
27258
28240
|
});
|
|
27259
28241
|
registerProjectRosterRoutes(app2, { service: rosterService });
|
|
@@ -27264,7 +28246,7 @@ var registerLatticeRoutes = (app2, channelDeps, options = {}) => {
|
|
|
27264
28246
|
createProject: projectStore.createProject.bind(projectStore)
|
|
27265
28247
|
},
|
|
27266
28248
|
workspaceStore: {
|
|
27267
|
-
getWorkspaceById: (tenantId, id3) => (0,
|
|
28249
|
+
getWorkspaceById: (tenantId, id3) => (0, import_core54.getStoreLattice)("default", "workspace").store.getWorkspaceById(tenantId, id3)
|
|
27268
28250
|
},
|
|
27269
28251
|
membershipStore: {
|
|
27270
28252
|
list: projectMembershipStore.list.bind(projectMembershipStore),
|
|
@@ -27287,7 +28269,7 @@ var registerLatticeRoutes = (app2, channelDeps, options = {}) => {
|
|
|
27287
28269
|
getUsersByTenant: userTenantLinkStore.getUsersByTenant.bind(userTenantLinkStore)
|
|
27288
28270
|
},
|
|
27289
28271
|
userStore: {
|
|
27290
|
-
getUserById: (id3) => (0,
|
|
28272
|
+
getUserById: (id3) => (0, import_core54.getStoreLattice)("default", "user").store.getUserById(id3).then((u) => u ? { id: u.id, name: u.name, email: u.email } : null)
|
|
27291
28273
|
},
|
|
27292
28274
|
assistantStore: {
|
|
27293
28275
|
getAssistantById: assistantStore.getAssistantById.bind(assistantStore),
|
|
@@ -27309,28 +28291,30 @@ var registerLatticeRoutes = (app2, channelDeps, options = {}) => {
|
|
|
27309
28291
|
}
|
|
27310
28292
|
});
|
|
27311
28293
|
registerCapabilityBundleRoutes(app2, new CapabilityBundleController({
|
|
27312
|
-
bundleStore: (0,
|
|
28294
|
+
bundleStore: (0, import_core54.getStoreLattice)("default", "capabilityBundle").store,
|
|
27313
28295
|
projectStore
|
|
27314
28296
|
}, { authRequired: process.env.AUTH_REQUIRED === "true" }));
|
|
27315
|
-
|
|
27316
|
-
providerStore: (0,
|
|
28297
|
+
const modelProviderController = new ModelProviderController({
|
|
28298
|
+
providerStore: (0, import_core54.getStoreLattice)("default", "modelProvider").store,
|
|
27317
28299
|
userTenantLinkStore,
|
|
27318
28300
|
registry: {
|
|
27319
|
-
register: (tenantId, modelKey2, config) =>
|
|
27320
|
-
has: (tenantId, modelKey2) =>
|
|
27321
|
-
remove: (tenantId, modelKey2) =>
|
|
27322
|
-
listRegistered: (tenantId) =>
|
|
27323
|
-
}
|
|
27324
|
-
}, { authRequired: process.env.AUTH_REQUIRED === "true" })
|
|
28301
|
+
register: (tenantId, modelKey2, config) => import_core54.modelLatticeManager.registerLatticeWithTenant(tenantId, modelKey2, config),
|
|
28302
|
+
has: (tenantId, modelKey2) => import_core54.modelLatticeManager.hasLatticeWithTenant(tenantId, modelKey2),
|
|
28303
|
+
remove: (tenantId, modelKey2) => import_core54.modelLatticeManager.removeLatticeWithTenant(tenantId, modelKey2),
|
|
28304
|
+
listRegistered: (tenantId) => import_core54.modelLatticeManager.getLatticeKeysByTenant(tenantId)
|
|
28305
|
+
}
|
|
28306
|
+
}, { authRequired: process.env.AUTH_REQUIRED === "true" });
|
|
28307
|
+
registerModelProviderRoutes(app2, modelProviderController);
|
|
28308
|
+
void modelProviderController.hydrateRegistry().catch(() => void 0);
|
|
27325
28309
|
registerAgentWebAppRoutes(app2, {
|
|
27326
28310
|
service: new AgentWebAppService({
|
|
27327
28311
|
webAppStore,
|
|
27328
28312
|
assistantStore,
|
|
27329
28313
|
projectStore,
|
|
27330
|
-
modelRegistry: { has: (key) =>
|
|
28314
|
+
modelRegistry: { has: (key) => import_core54.modelLatticeManager.hasLattice(key) },
|
|
27331
28315
|
configuredAgentResolver: createConfiguredAgentResolver({
|
|
27332
|
-
hydrate: (tenantId) =>
|
|
27333
|
-
has: (tenantId, assistantId) =>
|
|
28316
|
+
hydrate: (tenantId) => import_core54.agentLatticeManager.initializeStoredAssistantsForTenant(tenantId),
|
|
28317
|
+
has: (tenantId, assistantId) => import_core54.agentLatticeManager.hasAgentLatticeWithTenant(tenantId, assistantId)
|
|
27334
28318
|
})
|
|
27335
28319
|
})
|
|
27336
28320
|
});
|
|
@@ -27367,28 +28351,28 @@ var registerLatticeRoutes = (app2, channelDeps, options = {}) => {
|
|
|
27367
28351
|
},
|
|
27368
28352
|
tasks: taskStore,
|
|
27369
28353
|
workItems: taskWorkItemStore,
|
|
27370
|
-
projectMutationMutex:
|
|
28354
|
+
projectMutationMutex: import_core54.projectMutationMutex,
|
|
27371
28355
|
...projectTaskComposition ? { commands: taskCommandService } : {}
|
|
27372
28356
|
}),
|
|
27373
28357
|
service: new AgentWebAppRuntimeService({
|
|
27374
28358
|
webAppStore,
|
|
27375
|
-
threadStore: (0,
|
|
28359
|
+
threadStore: (0, import_core54.getStoreLattice)("default", "thread").store,
|
|
27376
28360
|
projectStore,
|
|
27377
28361
|
assistantResolver: {
|
|
27378
28362
|
resolve: async (tenantId, assistantId) => {
|
|
27379
28363
|
const stored = await assistantStore.getAssistantById(tenantId, assistantId);
|
|
27380
28364
|
if (stored) return { id: stored.id, name: stored.name, description: stored.description };
|
|
27381
|
-
await
|
|
27382
|
-
const config =
|
|
28365
|
+
await import_core54.agentLatticeManager.initializeStoredAssistantsForTenant(tenantId);
|
|
28366
|
+
const config = import_core54.agentLatticeManager.getAgentConfigWithTenant(tenantId, assistantId);
|
|
27383
28367
|
return config ? { id: assistantId, name: config.name, description: config.description } : null;
|
|
27384
28368
|
}
|
|
27385
28369
|
},
|
|
27386
28370
|
modelRegistry: {
|
|
27387
|
-
has: (key) =>
|
|
28371
|
+
has: (key) => import_core54.modelLatticeManager.hasLattice(key),
|
|
27388
28372
|
label: (key) => key
|
|
27389
28373
|
},
|
|
27390
28374
|
messageReader: {
|
|
27391
|
-
getCurrentMessages: ({ tenantId, assistantId, threadId, workspaceId, projectId }) =>
|
|
28375
|
+
getCurrentMessages: ({ tenantId, assistantId, threadId, workspaceId, projectId }) => import_core54.agentInstanceManager.getAgentForRead({
|
|
27392
28376
|
tenant_id: tenantId,
|
|
27393
28377
|
assistant_id: assistantId,
|
|
27394
28378
|
thread_id: threadId,
|
|
@@ -27397,7 +28381,7 @@ var registerLatticeRoutes = (app2, channelDeps, options = {}) => {
|
|
|
27397
28381
|
}).getCurrentMessages()
|
|
27398
28382
|
},
|
|
27399
28383
|
agentResolver: {
|
|
27400
|
-
getAgent: ({ tenantId, assistantId, threadId, workspaceId, projectId }) =>
|
|
28384
|
+
getAgent: ({ tenantId, assistantId, threadId, workspaceId, projectId }) => import_core54.agentInstanceManager.getAgent({
|
|
27401
28385
|
tenant_id: tenantId,
|
|
27402
28386
|
assistant_id: assistantId,
|
|
27403
28387
|
thread_id: threadId,
|
|
@@ -27415,8 +28399,8 @@ var registerLatticeRoutes = (app2, channelDeps, options = {}) => {
|
|
|
27415
28399
|
if (webApp.tenantId !== preview.tenantId) return false;
|
|
27416
28400
|
const assistant = await assistantStore.getAssistantById(preview.tenantId, webApp.assistantId);
|
|
27417
28401
|
if (assistant) return !assistant.ownerUserId || assistant.ownerUserId === preview.userId;
|
|
27418
|
-
await
|
|
27419
|
-
return
|
|
28402
|
+
await import_core54.agentLatticeManager.initializeStoredAssistantsForTenant(preview.tenantId);
|
|
28403
|
+
return import_core54.agentLatticeManager.hasAgentLatticeWithTenant(preview.tenantId, webApp.assistantId);
|
|
27420
28404
|
}
|
|
27421
28405
|
})
|
|
27422
28406
|
});
|
|
@@ -27473,14 +28457,14 @@ var registerLatticeRoutes = (app2, channelDeps, options = {}) => {
|
|
|
27473
28457
|
app2.post("/api/personal-assistant", createPersonalAssistant);
|
|
27474
28458
|
app2.get("/api/personal-assistant", getPersonalAssistant);
|
|
27475
28459
|
app2.delete("/api/personal-assistant", deletePersonalAssistant);
|
|
27476
|
-
|
|
28460
|
+
import_core54.executionAuthorityRegistry.register({
|
|
27477
28461
|
id: "project-lifecycle",
|
|
27478
28462
|
matches: isProjectLifecycleTask,
|
|
27479
28463
|
code: "PROJECT_TASK_EXECUTION_MANAGED",
|
|
27480
28464
|
message: "Project tasks are executed by the durable Project queue runtime",
|
|
27481
28465
|
onManagedStart: async (task, options2) => {
|
|
27482
28466
|
if (!projectTaskComposition && options2?.agentId && options2.agentId !== task.ownerId) {
|
|
27483
|
-
throw new
|
|
28467
|
+
throw new import_core54.ManagedTaskStartError(
|
|
27484
28468
|
"PROJECT_TASK_RUNTIME_UNAVAILABLE",
|
|
27485
28469
|
"Project task ownership transfer requires the Project task runtime.",
|
|
27486
28470
|
{ hint: "Project task execution is disabled; enable the Project task runtime or dispatch to the current owner." }
|
|
@@ -27493,17 +28477,21 @@ var registerLatticeRoutes = (app2, channelDeps, options = {}) => {
|
|
|
27493
28477
|
threads: taskThreadService,
|
|
27494
28478
|
reassignmentAuthorizer,
|
|
27495
28479
|
lifecycle: taskLifecycle,
|
|
27496
|
-
mutex:
|
|
28480
|
+
mutex: import_core54.projectMutationMutex
|
|
27497
28481
|
}) : void 0;
|
|
27498
28482
|
const admitted = transferred ?? task;
|
|
27499
28483
|
if (!admitted.workspaceId || !admitted.projectId) return;
|
|
27500
|
-
|
|
27501
|
-
|
|
27502
|
-
|
|
27503
|
-
|
|
27504
|
-
|
|
27505
|
-
|
|
27506
|
-
|
|
28484
|
+
const markerUpdated = await taskStore.update(admitted.tenantId, admitted.id, {
|
|
28485
|
+
context: withExecutionRequest(admitted.context, (/* @__PURE__ */ new Date()).toISOString())
|
|
28486
|
+
}).catch(() => null);
|
|
28487
|
+
const eventTask = markerUpdated ?? admitted;
|
|
28488
|
+
void import_core54.projectTaskAdmissionNotifier.publish({
|
|
28489
|
+
tenantId: eventTask.tenantId,
|
|
28490
|
+
workspaceId: eventTask.workspaceId,
|
|
28491
|
+
projectId: eventTask.projectId,
|
|
28492
|
+
taskId: eventTask.id,
|
|
28493
|
+
ownerId: eventTask.ownerId,
|
|
28494
|
+
updatedAt: eventTask.updatedAt.toISOString()
|
|
27507
28495
|
});
|
|
27508
28496
|
}
|
|
27509
28497
|
});
|
|
@@ -27511,7 +28499,7 @@ var registerLatticeRoutes = (app2, channelDeps, options = {}) => {
|
|
|
27511
28499
|
access: accessService,
|
|
27512
28500
|
tasks: taskStore,
|
|
27513
28501
|
workItems: taskWorkItemStore,
|
|
27514
|
-
projectMutationMutex:
|
|
28502
|
+
projectMutationMutex: import_core54.projectMutationMutex,
|
|
27515
28503
|
commands: taskCommandService,
|
|
27516
28504
|
readableProjects: async ({ tenantId, userId, workspaceId }) => {
|
|
27517
28505
|
const projects = await projectStore.getProjectsByWorkspace(tenantId, workspaceId);
|
|
@@ -27793,9 +28781,9 @@ function tryCreateProjectTaskRuntime(input) {
|
|
|
27793
28781
|
let stores;
|
|
27794
28782
|
try {
|
|
27795
28783
|
stores = {
|
|
27796
|
-
tenants: (0,
|
|
27797
|
-
workspaces: (0,
|
|
27798
|
-
queue: (0,
|
|
28784
|
+
tenants: (0, import_core54.getStoreLattice)("default", "tenant").store,
|
|
28785
|
+
workspaces: (0, import_core54.getStoreLattice)("default", "workspace").store,
|
|
28786
|
+
queue: (0, import_core54.getStoreLattice)("default", "threadMessageQueue").store
|
|
27799
28787
|
};
|
|
27800
28788
|
const missing = missingRuntimeMethod(input, stores);
|
|
27801
28789
|
if (missing) return { reason: missing };
|
|
@@ -27827,7 +28815,7 @@ function createRuntime(input, stores, log2) {
|
|
|
27827
28815
|
const controller = new AbortController();
|
|
27828
28816
|
const mutex = new ProjectTaskExecutionMutex();
|
|
27829
28817
|
const threads = new ProjectTaskThreadService({ threads: input.threadStore, idFactory: import_node_crypto26.randomUUID });
|
|
27830
|
-
const lifecycle = (0,
|
|
28818
|
+
const lifecycle = (0, import_core54.createTaskLifecycleService)({ taskStore: input.taskStore, workItemStore: input.taskWorkItemStore });
|
|
27831
28819
|
const projection = new RoomProjectionService({
|
|
27832
28820
|
messages: input.projectRoomMessageStore,
|
|
27833
28821
|
events: input.taskWorkItemStore,
|
|
@@ -27837,7 +28825,7 @@ function createRuntime(input, stores, log2) {
|
|
|
27837
28825
|
realtime: input.realtime,
|
|
27838
28826
|
idFactory: import_node_crypto26.randomUUID
|
|
27839
28827
|
});
|
|
27840
|
-
const agentFor = (task, thread) =>
|
|
28828
|
+
const agentFor = (task, thread) => import_core54.agentInstanceManager.getAgent({
|
|
27841
28829
|
tenant_id: task.tenantId,
|
|
27842
28830
|
assistant_id: task.ownerId,
|
|
27843
28831
|
thread_id: thread.id,
|
|
@@ -27851,7 +28839,7 @@ function createRuntime(input, stores, log2) {
|
|
|
27851
28839
|
bots: input.projectBotMembershipStore,
|
|
27852
28840
|
threads,
|
|
27853
28841
|
lifecycle,
|
|
27854
|
-
dispatcher: (0,
|
|
28842
|
+
dispatcher: (0, import_core54.createTrustedAgentMessageDispatcher)((scope) => import_core54.agentInstanceManager.getAgent(scope)),
|
|
27855
28843
|
queue: stores.queue,
|
|
27856
28844
|
agentFor
|
|
27857
28845
|
}, {
|
|
@@ -27878,8 +28866,8 @@ function createRuntime(input, stores, log2) {
|
|
|
27878
28866
|
const taskLifecycleListener = ((event) => {
|
|
27879
28867
|
void observer.listener(event);
|
|
27880
28868
|
});
|
|
27881
|
-
const unsubscribe =
|
|
27882
|
-
const unsubscribeAdmission =
|
|
28869
|
+
const unsubscribe = import_core54.taskLifecycleNotifier.subscribe(taskLifecycleListener);
|
|
28870
|
+
const unsubscribeAdmission = import_core54.projectTaskAdmissionNotifier.subscribe((event, signal) => {
|
|
27883
28871
|
observer.admit(event, signal);
|
|
27884
28872
|
});
|
|
27885
28873
|
let reconciliationWork;
|
|
@@ -28026,12 +29014,12 @@ function registerResourceRoutes(app2, controller) {
|
|
|
28026
29014
|
}
|
|
28027
29015
|
|
|
28028
29016
|
// src/export_registrations/index.ts
|
|
28029
|
-
var
|
|
29017
|
+
var import_core65 = require("@axiom-lattice/core");
|
|
28030
29018
|
|
|
28031
29019
|
// src/export_registrations/skill.registration.ts
|
|
28032
|
-
var
|
|
29020
|
+
var import_core55 = require("@axiom-lattice/core");
|
|
28033
29021
|
function getStore(context) {
|
|
28034
|
-
return new
|
|
29022
|
+
return new import_core55.SandboxSkillStore({
|
|
28035
29023
|
workspaceId: context?.workspaceId,
|
|
28036
29024
|
projectId: context?.projectId
|
|
28037
29025
|
});
|
|
@@ -28049,7 +29037,7 @@ var skillRegistration = {
|
|
|
28049
29037
|
async listForExport(tenantId, context) {
|
|
28050
29038
|
const store2 = getStore(context);
|
|
28051
29039
|
const skills = await store2.getAllSkills(tenantId, toStoreContext(context));
|
|
28052
|
-
return skills.filter((s) => !(0,
|
|
29040
|
+
return skills.filter((s) => !(0, import_core55.isBuiltInSkill)(s.id)).map((s) => ({
|
|
28053
29041
|
_exportId: "",
|
|
28054
29042
|
data: {
|
|
28055
29043
|
id: s.id,
|
|
@@ -28114,7 +29102,7 @@ var skillRegistration = {
|
|
|
28114
29102
|
const insertions = [];
|
|
28115
29103
|
for (const entity of entities) {
|
|
28116
29104
|
const id3 = entity.data.id;
|
|
28117
|
-
if ((0,
|
|
29105
|
+
if ((0, import_core55.isBuiltInSkill)(id3)) continue;
|
|
28118
29106
|
if (existingIds.has(id3)) {
|
|
28119
29107
|
conflicts.push({
|
|
28120
29108
|
_exportId: entity._exportId,
|
|
@@ -28173,9 +29161,9 @@ var skillRegistration = {
|
|
|
28173
29161
|
};
|
|
28174
29162
|
|
|
28175
29163
|
// src/export_registrations/agent.registration.ts
|
|
28176
|
-
var
|
|
29164
|
+
var import_core56 = require("@axiom-lattice/core");
|
|
28177
29165
|
function getStore2() {
|
|
28178
|
-
return (0,
|
|
29166
|
+
return (0, import_core56.getStoreLattice)("default", "assistant").store;
|
|
28179
29167
|
}
|
|
28180
29168
|
var agentRegistration = {
|
|
28181
29169
|
entityType: "agent",
|
|
@@ -28255,9 +29243,9 @@ var agentRegistration = {
|
|
|
28255
29243
|
};
|
|
28256
29244
|
|
|
28257
29245
|
// src/export_registrations/database-config.registration.ts
|
|
28258
|
-
var
|
|
29246
|
+
var import_core57 = require("@axiom-lattice/core");
|
|
28259
29247
|
function getStore3() {
|
|
28260
|
-
return (0,
|
|
29248
|
+
return (0, import_core57.getStoreLattice)("default", "database").store;
|
|
28261
29249
|
}
|
|
28262
29250
|
var databaseConfigRegistration = {
|
|
28263
29251
|
entityType: "database_config",
|
|
@@ -28337,9 +29325,9 @@ var databaseConfigRegistration = {
|
|
|
28337
29325
|
};
|
|
28338
29326
|
|
|
28339
29327
|
// src/export_registrations/metrics-config.registration.ts
|
|
28340
|
-
var
|
|
29328
|
+
var import_core58 = require("@axiom-lattice/core");
|
|
28341
29329
|
function getStore4() {
|
|
28342
|
-
return (0,
|
|
29330
|
+
return (0, import_core58.getStoreLattice)("default", "metrics").store;
|
|
28343
29331
|
}
|
|
28344
29332
|
var metricsConfigRegistration = {
|
|
28345
29333
|
entityType: "metrics_config",
|
|
@@ -28419,9 +29407,9 @@ var metricsConfigRegistration = {
|
|
|
28419
29407
|
};
|
|
28420
29408
|
|
|
28421
29409
|
// src/export_registrations/mcp-config.registration.ts
|
|
28422
|
-
var
|
|
29410
|
+
var import_core59 = require("@axiom-lattice/core");
|
|
28423
29411
|
function getStore5() {
|
|
28424
|
-
return (0,
|
|
29412
|
+
return (0, import_core59.getStoreLattice)("default", "mcp").store;
|
|
28425
29413
|
}
|
|
28426
29414
|
var mcpConfigRegistration = {
|
|
28427
29415
|
entityType: "mcp_config",
|
|
@@ -28504,9 +29492,9 @@ var mcpConfigRegistration = {
|
|
|
28504
29492
|
};
|
|
28505
29493
|
|
|
28506
29494
|
// src/export_registrations/connection.registration.ts
|
|
28507
|
-
var
|
|
29495
|
+
var import_core60 = require("@axiom-lattice/core");
|
|
28508
29496
|
function getStore6() {
|
|
28509
|
-
return (0,
|
|
29497
|
+
return (0, import_core60.getStoreLattice)("default", "connection").store;
|
|
28510
29498
|
}
|
|
28511
29499
|
async function listAllConnections(tenantId) {
|
|
28512
29500
|
const store2 = getStore6();
|
|
@@ -28588,9 +29576,9 @@ var connectionRegistration = {
|
|
|
28588
29576
|
};
|
|
28589
29577
|
|
|
28590
29578
|
// src/export_registrations/collection.registration.ts
|
|
28591
|
-
var
|
|
29579
|
+
var import_core61 = require("@axiom-lattice/core");
|
|
28592
29580
|
function getStore7() {
|
|
28593
|
-
return (0,
|
|
29581
|
+
return (0, import_core61.getStoreLattice)("default", "collection").store;
|
|
28594
29582
|
}
|
|
28595
29583
|
var collectionRegistration = {
|
|
28596
29584
|
entityType: "collection",
|
|
@@ -28661,7 +29649,7 @@ var collectionRegistration = {
|
|
|
28661
29649
|
};
|
|
28662
29650
|
|
|
28663
29651
|
// src/export_registrations/channel-installation.registration.ts
|
|
28664
|
-
var
|
|
29652
|
+
var import_core62 = require("@axiom-lattice/core");
|
|
28665
29653
|
var import_crypto11 = require("crypto");
|
|
28666
29654
|
var UUID_PATTERN2 = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
28667
29655
|
var PUBLIC_CHANNELS = /* @__PURE__ */ new Set(["lark", "email", "slack", "wechat"]);
|
|
@@ -28695,7 +29683,7 @@ function validateImportData(data) {
|
|
|
28695
29683
|
};
|
|
28696
29684
|
}
|
|
28697
29685
|
function getStore8() {
|
|
28698
|
-
return (0,
|
|
29686
|
+
return (0, import_core62.getStoreLattice)("default", "channelInstallation").store;
|
|
28699
29687
|
}
|
|
28700
29688
|
function getOverwriteError(tenantId, incomingChannel, existing) {
|
|
28701
29689
|
if (!existing) return "Channel installation overwrite target must exist";
|
|
@@ -28829,9 +29817,9 @@ var channelInstallationRegistration = {
|
|
|
28829
29817
|
};
|
|
28830
29818
|
|
|
28831
29819
|
// src/export_registrations/menu.registration.ts
|
|
28832
|
-
var
|
|
29820
|
+
var import_core63 = require("@axiom-lattice/core");
|
|
28833
29821
|
function getStore9() {
|
|
28834
|
-
return (0,
|
|
29822
|
+
return (0, import_core63.getStoreLattice)("default", "menu").store;
|
|
28835
29823
|
}
|
|
28836
29824
|
var menuRegistration = {
|
|
28837
29825
|
entityType: "menu",
|
|
@@ -28909,9 +29897,9 @@ var menuRegistration = {
|
|
|
28909
29897
|
};
|
|
28910
29898
|
|
|
28911
29899
|
// src/export_registrations/eval.registration.ts
|
|
28912
|
-
var
|
|
29900
|
+
var import_core64 = require("@axiom-lattice/core");
|
|
28913
29901
|
function getStore10() {
|
|
28914
|
-
return (0,
|
|
29902
|
+
return (0, import_core64.getStoreLattice)("default", "eval").store;
|
|
28915
29903
|
}
|
|
28916
29904
|
var evalRegistration = {
|
|
28917
29905
|
entityType: "eval",
|
|
@@ -29237,7 +30225,7 @@ var evalRegistration = {
|
|
|
29237
30225
|
|
|
29238
30226
|
// src/export_registrations/index.ts
|
|
29239
30227
|
function registerAllBuiltinEntities() {
|
|
29240
|
-
const registry =
|
|
30228
|
+
const registry = import_core65.ExportableEntityRegistry.getInstance();
|
|
29241
30229
|
registry.register(skillRegistration);
|
|
29242
30230
|
registry.register(agentRegistration);
|
|
29243
30231
|
registry.register(databaseConfigRegistration);
|
|
@@ -29368,7 +30356,7 @@ function createAuditLoggerMiddleware() {
|
|
|
29368
30356
|
}
|
|
29369
30357
|
|
|
29370
30358
|
// src/index.ts
|
|
29371
|
-
var
|
|
30359
|
+
var import_core91 = require("@axiom-lattice/core");
|
|
29372
30360
|
|
|
29373
30361
|
// src/swagger.ts
|
|
29374
30362
|
var import_swagger = __toESM(require("@fastify/swagger"));
|
|
@@ -29434,7 +30422,8 @@ var configureSwagger = async (app2, customSwaggerConfig, customSwaggerUiConfig)
|
|
|
29434
30422
|
|
|
29435
30423
|
// src/services/agent_task_consumer.ts
|
|
29436
30424
|
var import_node_crypto27 = require("crypto");
|
|
29437
|
-
var
|
|
30425
|
+
var import_core66 = require("@axiom-lattice/core");
|
|
30426
|
+
var import_protocols31 = require("@axiom-lattice/protocols");
|
|
29438
30427
|
var handleAgentTask = async (taskRequest, retryCount = 0) => {
|
|
29439
30428
|
const {
|
|
29440
30429
|
assistant_id,
|
|
@@ -29452,7 +30441,8 @@ var handleAgentTask = async (taskRequest, retryCount = 0) => {
|
|
|
29452
30441
|
console.log(
|
|
29453
30442
|
`\u5F00\u59CB\u5904\u7406\u4EFB\u52A1 [assistant_id: ${assistant_id}, thread_id: ${thread_id}]`
|
|
29454
30443
|
);
|
|
29455
|
-
const
|
|
30444
|
+
const scope = (0, import_protocols31.resolveRunScope)(runConfig);
|
|
30445
|
+
const agent = import_core66.agentInstanceManager.getAgent({ assistant_id, thread_id, tenant_id, workspace_id: scope.workspaceId, project_id: scope.projectId, custom_run_config: runConfig });
|
|
29456
30446
|
if (callback_event) {
|
|
29457
30447
|
const callbackEvent = callback_event;
|
|
29458
30448
|
const messageId = typeof input?.id === "string" && input.id !== "" ? input.id : (0, import_node_crypto27.randomUUID)();
|
|
@@ -29473,18 +30463,18 @@ var handleAgentTask = async (taskRequest, retryCount = 0) => {
|
|
|
29473
30463
|
const onCompleted = (evt) => {
|
|
29474
30464
|
if (!belongsToMessage(evt)) return;
|
|
29475
30465
|
settle(() => {
|
|
29476
|
-
|
|
30466
|
+
import_core66.eventBus.publish(callbackEvent, {
|
|
29477
30467
|
success: true,
|
|
29478
30468
|
state: evt.state
|
|
29479
30469
|
});
|
|
29480
30470
|
if (main_thread_id && main_tenant_id) {
|
|
29481
30471
|
try {
|
|
29482
|
-
const mainAgent =
|
|
30472
|
+
const mainAgent = import_core66.agentInstanceManager.getAgent({
|
|
29483
30473
|
assistant_id: main_assistant_id ?? assistant_id,
|
|
29484
30474
|
thread_id: main_thread_id,
|
|
29485
30475
|
tenant_id: main_tenant_id,
|
|
29486
|
-
workspace_id:
|
|
29487
|
-
project_id:
|
|
30476
|
+
workspace_id: scope.workspaceId,
|
|
30477
|
+
project_id: scope.projectId
|
|
29488
30478
|
});
|
|
29489
30479
|
if (mainAgent) {
|
|
29490
30480
|
const messages = evt.state?.values?.messages;
|
|
@@ -29512,7 +30502,7 @@ ${summary}`
|
|
|
29512
30502
|
const onInterrupted = (evt) => {
|
|
29513
30503
|
if (!belongsToMessage(evt)) return;
|
|
29514
30504
|
settle(() => {
|
|
29515
|
-
|
|
30505
|
+
import_core66.eventBus.publish(callbackEvent, {
|
|
29516
30506
|
success: true,
|
|
29517
30507
|
state: evt.state
|
|
29518
30508
|
});
|
|
@@ -29521,7 +30511,7 @@ ${summary}`
|
|
|
29521
30511
|
const onFailed = (evt) => {
|
|
29522
30512
|
if (!belongsToMessage(evt)) return;
|
|
29523
30513
|
settle(() => {
|
|
29524
|
-
|
|
30514
|
+
import_core66.eventBus.publish(callbackEvent, {
|
|
29525
30515
|
success: false,
|
|
29526
30516
|
error: evt?.error instanceof Error ? evt.error.message : typeof evt?.error === "string" ? evt.error : "Agent execution failed"
|
|
29527
30517
|
});
|
|
@@ -29536,13 +30526,13 @@ ${summary}`
|
|
|
29536
30526
|
agent.subscribe("message:interrupted", onInterrupted);
|
|
29537
30527
|
agent.subscribe("message:failed", onFailed);
|
|
29538
30528
|
try {
|
|
29539
|
-
await agent.addMessage({ input: { ...input, id: messageId }, command, custom_run_config: runConfig },
|
|
30529
|
+
await agent.addMessage({ input: { ...input, id: messageId }, command, custom_run_config: runConfig }, import_core66.QueueMode.STEER);
|
|
29540
30530
|
} catch (error) {
|
|
29541
30531
|
dispose();
|
|
29542
30532
|
throw error;
|
|
29543
30533
|
}
|
|
29544
30534
|
} else {
|
|
29545
|
-
await agent.addMessage({ input, command, custom_run_config: runConfig },
|
|
30535
|
+
await agent.addMessage({ input, command, custom_run_config: runConfig }, import_core66.QueueMode.STEER);
|
|
29546
30536
|
}
|
|
29547
30537
|
return true;
|
|
29548
30538
|
} catch (error) {
|
|
@@ -29561,7 +30551,7 @@ ${summary}`
|
|
|
29561
30551
|
return handleAgentTask(taskRequest, nextRetryCount);
|
|
29562
30552
|
}
|
|
29563
30553
|
if (callback_event) {
|
|
29564
|
-
|
|
30554
|
+
import_core66.eventBus.publish(callback_event, {
|
|
29565
30555
|
success: false,
|
|
29566
30556
|
error: error instanceof Error ? error.message : String(error)
|
|
29567
30557
|
});
|
|
@@ -29598,7 +30588,7 @@ var _AgentTaskConsumer = class _AgentTaskConsumer {
|
|
|
29598
30588
|
* 初始化事件监听和队列轮询
|
|
29599
30589
|
*/
|
|
29600
30590
|
initialize() {
|
|
29601
|
-
|
|
30591
|
+
import_core66.eventBus.subscribe(import_core66.AGENT_TASK_EVENT, this.trigger_agent_task.bind(this));
|
|
29602
30592
|
this.startPollingQueue();
|
|
29603
30593
|
console.log("Agent\u4EFB\u52A1\u6D88\u8D39\u8005\u5DF2\u542F\u52A8\u5E76\u76D1\u542C\u4EFB\u52A1\u4E8B\u4EF6\u548C\u961F\u5217");
|
|
29604
30594
|
}
|
|
@@ -29717,7 +30707,7 @@ var _AgentTaskConsumer = class _AgentTaskConsumer {
|
|
|
29717
30707
|
handleAgentTask(taskRequest).catch((error) => {
|
|
29718
30708
|
console.error("\u5904\u7406Agent\u4EFB\u52A1\u65F6\u53D1\u751F\u672A\u6355\u83B7\u7684\u9519\u8BEF:", error);
|
|
29719
30709
|
if (taskRequest.callback_event) {
|
|
29720
|
-
|
|
30710
|
+
import_core66.eventBus.publish(taskRequest.callback_event, {
|
|
29721
30711
|
success: false,
|
|
29722
30712
|
error: error instanceof Error ? error.message : String(error)
|
|
29723
30713
|
});
|
|
@@ -29732,14 +30722,14 @@ _AgentTaskConsumer.agent_run_endpoint = "http://localhost:4001/api/runs";
|
|
|
29732
30722
|
var AgentTaskConsumer = _AgentTaskConsumer;
|
|
29733
30723
|
|
|
29734
30724
|
// src/index.ts
|
|
29735
|
-
var
|
|
30725
|
+
var import_core92 = require("@axiom-lattice/core");
|
|
29736
30726
|
|
|
29737
30727
|
// src/channels/ChannelInfrastructure.ts
|
|
29738
|
-
var
|
|
30728
|
+
var import_core68 = require("@axiom-lattice/core");
|
|
29739
30729
|
|
|
29740
30730
|
// src/router/MessageRouter.ts
|
|
29741
|
-
var
|
|
29742
|
-
var
|
|
30731
|
+
var import_core67 = require("@axiom-lattice/core");
|
|
30732
|
+
var import_protocols32 = require("@axiom-lattice/protocols");
|
|
29743
30733
|
var import_crypto12 = require("crypto");
|
|
29744
30734
|
var BindingNotFoundError = class extends Error {
|
|
29745
30735
|
constructor(message) {
|
|
@@ -29774,10 +30764,10 @@ function clarifyText(clarify) {
|
|
|
29774
30764
|
return ["```clarify", JSON.stringify({ questions: clarify.questions }), "```"].join("\n");
|
|
29775
30765
|
}
|
|
29776
30766
|
function exactDataValues(value, required, optional = []) {
|
|
29777
|
-
return (0,
|
|
30767
|
+
return (0, import_protocols32.snapshotExactRecord)(value, required, optional);
|
|
29778
30768
|
}
|
|
29779
30769
|
function uniqueNonemptyStrings(value) {
|
|
29780
|
-
const snapshot = (0,
|
|
30770
|
+
const snapshot = (0, import_protocols32.snapshotExactArray)(value);
|
|
29781
30771
|
if (!snapshot || snapshot.length === 0 || snapshot.some((entry) => typeof entry !== "string" || entry.length === 0)) return void 0;
|
|
29782
30772
|
const values = snapshot;
|
|
29783
30773
|
return new Set(values).size === values.length ? values : void 0;
|
|
@@ -30024,7 +31014,7 @@ var MessageRouter = class {
|
|
|
30024
31014
|
channel: message.channel,
|
|
30025
31015
|
adapterChannel: adapter.channel
|
|
30026
31016
|
}, "Thread resolved by adapter strategy");
|
|
30027
|
-
const threadStore = (0,
|
|
31017
|
+
const threadStore = (0, import_core67.getStoreLattice)("default", "thread").store;
|
|
30028
31018
|
try {
|
|
30029
31019
|
await threadStore.createThread(
|
|
30030
31020
|
tenantId,
|
|
@@ -30061,7 +31051,7 @@ var MessageRouter = class {
|
|
|
30061
31051
|
}
|
|
30062
31052
|
}
|
|
30063
31053
|
if (!threadId) {
|
|
30064
|
-
const threadStore = (0,
|
|
31054
|
+
const threadStore = (0, import_core67.getStoreLattice)("default", "thread").store;
|
|
30065
31055
|
const newThreadId = (0, import_crypto12.randomUUID)();
|
|
30066
31056
|
console.log({
|
|
30067
31057
|
event: "dispatch:thread:create",
|
|
@@ -30101,7 +31091,7 @@ var MessageRouter = class {
|
|
|
30101
31091
|
senderId: message.sender.id,
|
|
30102
31092
|
contentLength: message.content.text.length
|
|
30103
31093
|
}, "Dispatching to agent");
|
|
30104
|
-
const agent =
|
|
31094
|
+
const agent = import_core67.agentInstanceManager.getAgent({
|
|
30105
31095
|
tenant_id: tenantId,
|
|
30106
31096
|
assistant_id: agentId,
|
|
30107
31097
|
thread_id: threadId,
|
|
@@ -30289,7 +31279,7 @@ var MessageRouter = class {
|
|
|
30289
31279
|
|
|
30290
31280
|
// src/channels/room/RoomChannelAdapter.ts
|
|
30291
31281
|
var import_zod17 = require("zod");
|
|
30292
|
-
var
|
|
31282
|
+
var import_protocols33 = require("@axiom-lattice/protocols");
|
|
30293
31283
|
var roomConfigSchema = import_zod17.z.object({}).strict();
|
|
30294
31284
|
function createRoomChannelAdapter(writer) {
|
|
30295
31285
|
return {
|
|
@@ -30350,7 +31340,7 @@ function exactStrings(value, keys2) {
|
|
|
30350
31340
|
function exactValues2(value, required, optional = []) {
|
|
30351
31341
|
try {
|
|
30352
31342
|
if (typeof value !== "object" || value === null || Array.isArray(value)) return void 0;
|
|
30353
|
-
return (0,
|
|
31343
|
+
return (0, import_protocols33.snapshotExactRecord)(value, required, optional);
|
|
30354
31344
|
} catch {
|
|
30355
31345
|
return void 0;
|
|
30356
31346
|
}
|
|
@@ -30374,7 +31364,7 @@ function createChannelInfrastructure(deps) {
|
|
|
30374
31364
|
onMessageCommitted: deps.onMessageCommitted ?? (deps.realtime ? (message) => deps.realtime?.messageCreated(message) : void 0),
|
|
30375
31365
|
onCallbackFailure: (event) => deps.warn("project-room:message-commit-callback-failed", event)
|
|
30376
31366
|
};
|
|
30377
|
-
deps.adapterRegistry.register(createRoomChannelAdapter(new
|
|
31367
|
+
deps.adapterRegistry.register(createRoomChannelAdapter(new import_core68.RoomAgentMessageService(writerDeps)));
|
|
30378
31368
|
} catch (error) {
|
|
30379
31369
|
deps.warn("Room channel unavailable", { error: error instanceof Error ? error.message : String(error) });
|
|
30380
31370
|
}
|
|
@@ -30394,26 +31384,186 @@ async function prepareProjectTaskRuntime(runtime, log2) {
|
|
|
30394
31384
|
}
|
|
30395
31385
|
}
|
|
30396
31386
|
|
|
31387
|
+
// src/services/multiReplicaReadiness.ts
|
|
31388
|
+
var import_core69 = require("@axiom-lattice/core");
|
|
31389
|
+
var SHARED_STORE_KINDS = ["lease", "outbox", "threadMessageQueue", "task", "taskWorkItem"];
|
|
31390
|
+
function storeClassName(kind) {
|
|
31391
|
+
try {
|
|
31392
|
+
return (0, import_core69.getStoreLattice)("default", kind).store.constructor?.name;
|
|
31393
|
+
} catch {
|
|
31394
|
+
return void 0;
|
|
31395
|
+
}
|
|
31396
|
+
}
|
|
31397
|
+
function warnMultiReplicaReadiness(logger8) {
|
|
31398
|
+
if (typeof process.env.AXIOM_REPLICA_ID !== "string" || process.env.AXIOM_REPLICA_ID.trim() === "") return;
|
|
31399
|
+
for (const kind of SHARED_STORE_KINDS) {
|
|
31400
|
+
const name = storeClassName(kind);
|
|
31401
|
+
if (name === void 0 || !name.startsWith("InMemory")) continue;
|
|
31402
|
+
logger8.warn(`Multi-replica: store '${kind}' is ${name} (not shared); configure a shared store`, {
|
|
31403
|
+
phase: "multi_replica_readiness",
|
|
31404
|
+
store: kind
|
|
31405
|
+
});
|
|
31406
|
+
}
|
|
31407
|
+
if (!process.env.AUTH_TOKEN_SECRET?.trim() && !process.env.JWT_SECRET?.trim()) {
|
|
31408
|
+
logger8.warn(
|
|
31409
|
+
"Multi-replica: AUTH_TOKEN_SECRET/JWT_SECRET unset; console sessions are signed per-process and will not verify across replicas",
|
|
31410
|
+
{ phase: "multi_replica_readiness", env: "AUTH_TOKEN_SECRET" }
|
|
31411
|
+
);
|
|
31412
|
+
}
|
|
31413
|
+
if (!process.env.LATTICE_ENCRYPTION_KEY?.trim()) {
|
|
31414
|
+
logger8.warn(
|
|
31415
|
+
"Multi-replica: LATTICE_ENCRYPTION_KEY unset; stored credentials use the shared dev default and may not decrypt across differing keys",
|
|
31416
|
+
{ phase: "multi_replica_readiness", env: "LATTICE_ENCRYPTION_KEY" }
|
|
31417
|
+
);
|
|
31418
|
+
}
|
|
31419
|
+
logger8.warn(
|
|
31420
|
+
"Multi-replica: agent run SSE and resume_stream are process-local; route a thread's follow-up runs to the replica streaming it (sticky routing) or share the stream/queue state",
|
|
31421
|
+
{ phase: "multi_replica_readiness", feature: "agent-run-sse" }
|
|
31422
|
+
);
|
|
31423
|
+
}
|
|
31424
|
+
|
|
31425
|
+
// src/services/OutboxRetentionJob.ts
|
|
31426
|
+
var HOUR_MS = 60 * 60 * 1e3;
|
|
31427
|
+
var DEFAULT_INTERVAL_MS2 = 6 * HOUR_MS;
|
|
31428
|
+
var DEFAULT_INITIAL_DELAY_MS2 = 6e4;
|
|
31429
|
+
var AXIOM_OUTBOX_RETENTION_HOURS_ENV = "AXIOM_OUTBOX_RETENTION_HOURS";
|
|
31430
|
+
var DEFAULT_RETENTION_HOURS = 24;
|
|
31431
|
+
function parseRetentionHours(value) {
|
|
31432
|
+
if (value === void 0 || value === null) return DEFAULT_RETENTION_HOURS;
|
|
31433
|
+
if (typeof value !== "string") return void 0;
|
|
31434
|
+
const trimmed = value.trim();
|
|
31435
|
+
if (trimmed.length === 0) return DEFAULT_RETENTION_HOURS;
|
|
31436
|
+
const parsed = Number(trimmed);
|
|
31437
|
+
return Number.isSafeInteger(parsed) && parsed > 0 ? parsed : void 0;
|
|
31438
|
+
}
|
|
31439
|
+
var OutboxRetentionJob = class {
|
|
31440
|
+
/** @param deps Outbox slice, logger, and optional retention/interval bounds. */
|
|
31441
|
+
constructor(deps) {
|
|
31442
|
+
this.deps = deps;
|
|
31443
|
+
this.running = false;
|
|
31444
|
+
this.stopped = false;
|
|
31445
|
+
}
|
|
31446
|
+
/** Schedules one delayed sweep plus the recurring interval (both unref'd). */
|
|
31447
|
+
start() {
|
|
31448
|
+
if (this.stopped || this.deps.retentionMs === void 0) return;
|
|
31449
|
+
if (this.initial !== void 0 || this.interval !== void 0) return;
|
|
31450
|
+
this.initial = setTimeout(() => {
|
|
31451
|
+
this.initial = void 0;
|
|
31452
|
+
void this.runOnce();
|
|
31453
|
+
}, this.deps.initialDelayMs ?? DEFAULT_INITIAL_DELAY_MS2);
|
|
31454
|
+
this.initial.unref?.();
|
|
31455
|
+
this.interval = setInterval(() => void this.runOnce(), this.deps.intervalMs ?? DEFAULT_INTERVAL_MS2);
|
|
31456
|
+
this.interval.unref?.();
|
|
31457
|
+
}
|
|
31458
|
+
/**
|
|
31459
|
+
* Runs one age-based prune.
|
|
31460
|
+
*
|
|
31461
|
+
* @returns The number of rows removed (0 when disabled, overlapping, or on failure).
|
|
31462
|
+
*/
|
|
31463
|
+
async runOnce() {
|
|
31464
|
+
const retentionMs = this.deps.retentionMs;
|
|
31465
|
+
if (this.stopped || retentionMs === void 0 || this.running) return 0;
|
|
31466
|
+
this.running = true;
|
|
31467
|
+
try {
|
|
31468
|
+
const removed = await this.deps.outbox.pruneOlderThan(retentionMs);
|
|
31469
|
+
if (removed > 0) this.deps.log.info("outbox pruned", { removed });
|
|
31470
|
+
return removed;
|
|
31471
|
+
} catch (error) {
|
|
31472
|
+
this.deps.log.warn("outbox prune failed", {
|
|
31473
|
+
error: error instanceof Error ? error.message : String(error)
|
|
31474
|
+
});
|
|
31475
|
+
return 0;
|
|
31476
|
+
} finally {
|
|
31477
|
+
this.running = false;
|
|
31478
|
+
}
|
|
31479
|
+
}
|
|
31480
|
+
/** Stops the timers; an in-flight sweep finishes on its own. */
|
|
31481
|
+
stop() {
|
|
31482
|
+
this.stopped = true;
|
|
31483
|
+
if (this.initial !== void 0) {
|
|
31484
|
+
clearTimeout(this.initial);
|
|
31485
|
+
this.initial = void 0;
|
|
31486
|
+
}
|
|
31487
|
+
if (this.interval !== void 0) {
|
|
31488
|
+
clearInterval(this.interval);
|
|
31489
|
+
this.interval = void 0;
|
|
31490
|
+
}
|
|
31491
|
+
}
|
|
31492
|
+
};
|
|
31493
|
+
function createOutboxRetentionJob(deps) {
|
|
31494
|
+
const retentionMs = deps.retentionMs ?? resolveRetentionMs(process.env[AXIOM_OUTBOX_RETENTION_HOURS_ENV]);
|
|
31495
|
+
return new OutboxRetentionJob({ ...deps, retentionMs });
|
|
31496
|
+
}
|
|
31497
|
+
function resolveRetentionMs(value) {
|
|
31498
|
+
const hours = parseRetentionHours(value);
|
|
31499
|
+
return hours === void 0 ? void 0 : hours * HOUR_MS;
|
|
31500
|
+
}
|
|
31501
|
+
|
|
31502
|
+
// src/services/collaboration/roomEventSync.ts
|
|
31503
|
+
var ROOM_EVENT_TOPIC = "room-event";
|
|
31504
|
+
async function publishRoomEvent(outbox, owner, scope, serialized, sourceKey) {
|
|
31505
|
+
try {
|
|
31506
|
+
await outbox.append({
|
|
31507
|
+
topic: ROOM_EVENT_TOPIC,
|
|
31508
|
+
payload: { scope, serialized, sourceKey },
|
|
31509
|
+
originReplicaId: owner
|
|
31510
|
+
});
|
|
31511
|
+
} catch {
|
|
31512
|
+
}
|
|
31513
|
+
}
|
|
31514
|
+
function ingestRoomEvent(payload, broker) {
|
|
31515
|
+
const record = payload;
|
|
31516
|
+
const serialized = record?.serialized;
|
|
31517
|
+
if (typeof serialized !== "string" || serialized.length === 0) return false;
|
|
31518
|
+
const sourceKey = record?.sourceKey;
|
|
31519
|
+
if (typeof sourceKey === "string" && sourceKey.length > 0) {
|
|
31520
|
+
return broker.ingestForeignEvent(serialized, sourceKey);
|
|
31521
|
+
}
|
|
31522
|
+
return broker.ingestForeignEvent(serialized);
|
|
31523
|
+
}
|
|
31524
|
+
|
|
31525
|
+
// src/services/assistantRegistrySync.ts
|
|
31526
|
+
var ASSISTANT_CHANGE_EVENTS = ["assistant:created", "assistant:updated", "assistant:deleted"];
|
|
31527
|
+
var ASSISTANT_CHANGED_TOPIC = "assistant-changed";
|
|
31528
|
+
function bridgeAssistantEvents(subscribe, outbox, owner) {
|
|
31529
|
+
for (const event of ASSISTANT_CHANGE_EVENTS) {
|
|
31530
|
+
subscribe(event, (data) => {
|
|
31531
|
+
const tenantId = data?.tenantId;
|
|
31532
|
+
if (typeof tenantId !== "string" || tenantId.length === 0) return;
|
|
31533
|
+
void outbox.append({ topic: ASSISTANT_CHANGED_TOPIC, payload: { tenantId }, originReplicaId: owner }).catch(() => void 0);
|
|
31534
|
+
});
|
|
31535
|
+
}
|
|
31536
|
+
}
|
|
31537
|
+
async function handleAssistantChanged(payload, reload) {
|
|
31538
|
+
const tenantId = payload?.tenantId;
|
|
31539
|
+
if (typeof tenantId !== "string" || tenantId.length === 0) return;
|
|
31540
|
+
await reload(tenantId);
|
|
31541
|
+
}
|
|
31542
|
+
|
|
30397
31543
|
// src/index.ts
|
|
30398
|
-
var
|
|
31544
|
+
var import_protocols40 = require("@axiom-lattice/protocols");
|
|
31545
|
+
init_TopCallerRecovery();
|
|
31546
|
+
init_OrphanRecoveryRuntime();
|
|
31547
|
+
init_RecoveryCallerDeps();
|
|
31548
|
+
init_taskRunLiveness();
|
|
30399
31549
|
process.on("unhandledRejection", (reason, promise) => {
|
|
30400
31550
|
console.error("\u672A\u5904\u7406\u7684Promise\u62D2\u7EDD:", reason);
|
|
30401
31551
|
});
|
|
30402
31552
|
var DEFAULT_LOGGER_CONFIG = {
|
|
30403
31553
|
name: "default",
|
|
30404
31554
|
description: "Default logger for lattice-gateway service",
|
|
30405
|
-
type:
|
|
31555
|
+
type: import_protocols40.LoggerType.PINO,
|
|
30406
31556
|
serviceName: "lattice/gateway",
|
|
30407
31557
|
loggerName: "lattice/gateway"
|
|
30408
31558
|
};
|
|
30409
31559
|
var loggerLattice = initializeLogger(DEFAULT_LOGGER_CONFIG);
|
|
30410
31560
|
var logger7 = loggerLattice.client;
|
|
30411
31561
|
function initializeLogger(config) {
|
|
30412
|
-
if (
|
|
30413
|
-
|
|
31562
|
+
if (import_core92.loggerLatticeManager.hasLattice("default")) {
|
|
31563
|
+
import_core92.loggerLatticeManager.removeLattice("default");
|
|
30414
31564
|
}
|
|
30415
|
-
(0,
|
|
30416
|
-
return (0,
|
|
31565
|
+
(0, import_core92.registerLoggerLattice)("default", config);
|
|
31566
|
+
return (0, import_core92.getLoggerLattice)("default");
|
|
30417
31567
|
}
|
|
30418
31568
|
var app = (0, import_fastify.default)({
|
|
30419
31569
|
logger: false,
|
|
@@ -30474,7 +31624,7 @@ app.register(import_cors.default, {
|
|
|
30474
31624
|
origin: true,
|
|
30475
31625
|
methods: ["GET", "POST", "PUT", "DELETE", "OPTIONS", "PATCH"],
|
|
30476
31626
|
allowedHeaders: "*",
|
|
30477
|
-
exposedHeaders: ["Content-Type", "Content-Disposition"],
|
|
31627
|
+
exposedHeaders: ["Content-Type", "Content-Disposition", import_protocols40.REPLICA_HEADER, import_protocols40.AFFINITY_ECHO_HEADER],
|
|
30478
31628
|
credentials: true
|
|
30479
31629
|
});
|
|
30480
31630
|
app.register(import_sensible.default);
|
|
@@ -30510,7 +31660,7 @@ app.setErrorHandler((error, request, reply) => {
|
|
|
30510
31660
|
});
|
|
30511
31661
|
function getConfiguredSandboxProvider() {
|
|
30512
31662
|
const sandboxProviderType = process.env.SANDBOX_PROVIDER_TYPE || "microsandbox-remote";
|
|
30513
|
-
return (0,
|
|
31663
|
+
return (0, import_core92.createSandboxProvider)({
|
|
30514
31664
|
type: sandboxProviderType,
|
|
30515
31665
|
remoteBaseURL: process.env.SANDBOX_BASE_URL,
|
|
30516
31666
|
microsandboxServiceBaseURL: process.env.MICROSANDBOX_SERVICE_BASE_URL,
|
|
@@ -30526,7 +31676,7 @@ function getConfiguredSandboxProvider() {
|
|
|
30526
31676
|
}
|
|
30527
31677
|
async function restoreMcpConnections() {
|
|
30528
31678
|
try {
|
|
30529
|
-
const storeLattice = (0,
|
|
31679
|
+
const storeLattice = (0, import_core92.getStoreLattice)("default", "mcp");
|
|
30530
31680
|
const store2 = storeLattice.store;
|
|
30531
31681
|
if (!store2) {
|
|
30532
31682
|
logger7.info("MCP store not configured, skipping connection restoration");
|
|
@@ -30537,25 +31687,16 @@ async function restoreMcpConnections() {
|
|
|
30537
31687
|
);
|
|
30538
31688
|
if (configs.length === 0) return;
|
|
30539
31689
|
logger7.info(`Restoring ${configs.length} MCP server connections...`);
|
|
30540
|
-
|
|
30541
|
-
|
|
30542
|
-
|
|
30543
|
-
|
|
30544
|
-
|
|
30545
|
-
maxAttempts: config.config.retryAttempts,
|
|
30546
|
-
selectedTools: config.selectedTools
|
|
30547
|
-
});
|
|
30548
|
-
} catch (err) {
|
|
30549
|
-
logger7.warn(`Failed to prepare MCP server "${config.tenantId}/${config.key}"`, { error: err });
|
|
30550
|
-
}
|
|
30551
|
-
}
|
|
30552
|
-
await import_core82.mcpManager.connectAll();
|
|
31690
|
+
const deps = {
|
|
31691
|
+
store: store2,
|
|
31692
|
+
manager: import_core92.mcpManager,
|
|
31693
|
+
convertToConnection: import_core92.convertToConnection
|
|
31694
|
+
};
|
|
30553
31695
|
const results = await Promise.allSettled(
|
|
30554
31696
|
configs.map(
|
|
30555
|
-
(config) =>
|
|
30556
|
-
config.tenantId,
|
|
30557
|
-
|
|
30558
|
-
config.selectedTools
|
|
31697
|
+
(config) => reconcileMcpConfigChange(
|
|
31698
|
+
{ tenantId: config.tenantId, serverKey: config.key },
|
|
31699
|
+
deps
|
|
30559
31700
|
)
|
|
30560
31701
|
)
|
|
30561
31702
|
);
|
|
@@ -30563,7 +31704,7 @@ async function restoreMcpConnections() {
|
|
|
30563
31704
|
if (result.status === "rejected") {
|
|
30564
31705
|
const config = configs[index];
|
|
30565
31706
|
logger7.warn(
|
|
30566
|
-
`Failed to
|
|
31707
|
+
`Failed to restore MCP server "${config.tenantId}/${config.key}"`,
|
|
30567
31708
|
{ error: result.reason }
|
|
30568
31709
|
);
|
|
30569
31710
|
}
|
|
@@ -30590,9 +31731,9 @@ var start = async (config) => {
|
|
|
30590
31731
|
let projectRoomRealtimeRuntime;
|
|
30591
31732
|
if (projectRoomRealtimeMode === "single-gateway") {
|
|
30592
31733
|
projectRoomRealtimeRuntime = createProjectRoomRealtimeRuntime({
|
|
30593
|
-
tasks: (0,
|
|
30594
|
-
rooms: (0,
|
|
30595
|
-
memberships: (0,
|
|
31734
|
+
tasks: (0, import_core92.getStoreLattice)("default", "task").store,
|
|
31735
|
+
rooms: (0, import_core92.getStoreLattice)("default", "projectRoom").store,
|
|
31736
|
+
memberships: (0, import_core92.getStoreLattice)("default", "projectBotMembership").store,
|
|
30596
31737
|
log: { warn: (message, context) => logger7.warn(message, context) }
|
|
30597
31738
|
});
|
|
30598
31739
|
}
|
|
@@ -30606,7 +31747,7 @@ var start = async (config) => {
|
|
|
30606
31747
|
const infrastructure = createChannelInfrastructure({
|
|
30607
31748
|
adapterRegistry,
|
|
30608
31749
|
getStore: ((kind) => getStore11("default", kind).store),
|
|
30609
|
-
trustedDispatcher: (0,
|
|
31750
|
+
trustedDispatcher: (0, import_core92.createTrustedAgentMessageDispatcher)((scope) => import_core92.agentInstanceManager.getAgent(scope)),
|
|
30610
31751
|
middlewares: [
|
|
30611
31752
|
createDeduplicationMiddleware(),
|
|
30612
31753
|
createRateLimitMiddleware(),
|
|
@@ -30617,7 +31758,7 @@ var start = async (config) => {
|
|
|
30617
31758
|
});
|
|
30618
31759
|
const bindingStore = infrastructure.bindingRegistry;
|
|
30619
31760
|
const installationStore = infrastructure.installationStore;
|
|
30620
|
-
(0,
|
|
31761
|
+
(0, import_core91.setBindingRegistry)(bindingStore);
|
|
30621
31762
|
const router = infrastructure.router;
|
|
30622
31763
|
app.addHook("onClose", async () => router.dispose());
|
|
30623
31764
|
channelDeps = {
|
|
@@ -30633,10 +31774,10 @@ var start = async (config) => {
|
|
|
30633
31774
|
error: err instanceof Error ? err.message : String(err)
|
|
30634
31775
|
});
|
|
30635
31776
|
}
|
|
30636
|
-
(0,
|
|
31777
|
+
(0, import_core91.setEvalRunService)(evalRunner);
|
|
30637
31778
|
try {
|
|
30638
|
-
const menuStore = (0,
|
|
30639
|
-
(0,
|
|
31779
|
+
const menuStore = (0, import_core92.getStoreLattice)("default", "menu").store;
|
|
31780
|
+
(0, import_core91.setMenuRegistry)(menuStore);
|
|
30640
31781
|
logger7.info("Menu registry initialized");
|
|
30641
31782
|
} catch {
|
|
30642
31783
|
}
|
|
@@ -30653,10 +31794,10 @@ var start = async (config) => {
|
|
|
30653
31794
|
const { A2AAuthService: A2AAuthService2, parseEnvKeys: parseEnvKeys2 } = await Promise.resolve().then(() => (init_A2AAuthService(), A2AAuthService_exports));
|
|
30654
31795
|
const { registerA2AStandardRoutes: registerA2AStandardRoutes2 } = await Promise.resolve().then(() => (init_a2a_standard(), a2a_standard_exports));
|
|
30655
31796
|
const a2a = await Promise.resolve().then(() => (init_a2a(), a2a_exports));
|
|
30656
|
-
const a2aKeyStore = (0,
|
|
30657
|
-
const assistantStore = (0,
|
|
30658
|
-
const projectStore = (0,
|
|
30659
|
-
const taskStore = (0,
|
|
31797
|
+
const a2aKeyStore = (0, import_core92.getStoreLattice)("default", "a2aApiKey").store;
|
|
31798
|
+
const assistantStore = (0, import_core92.getStoreLattice)("default", "assistant").store;
|
|
31799
|
+
const projectStore = (0, import_core92.getStoreLattice)("default", "project").store;
|
|
31800
|
+
const taskStore = (0, import_core92.getStoreLattice)("default", "task").store;
|
|
30660
31801
|
const authService = new A2AAuthService2({
|
|
30661
31802
|
keyStore: a2aKeyStore,
|
|
30662
31803
|
assistantStore,
|
|
@@ -30695,8 +31836,8 @@ var start = async (config) => {
|
|
|
30695
31836
|
const { CollectionService: CollectionService2 } = await Promise.resolve().then(() => (init_collection_service(), collection_service_exports));
|
|
30696
31837
|
openLattice2.register(createKbProvider2(new CollectionService2()));
|
|
30697
31838
|
openLattice2.register(createOpenSandboxProvider2());
|
|
30698
|
-
const threadStore = (0,
|
|
30699
|
-
const assistantStore = (0,
|
|
31839
|
+
const threadStore = (0, import_core92.getStoreLattice)("default", "thread").store;
|
|
31840
|
+
const assistantStore = (0, import_core92.getStoreLattice)("default", "assistant").store;
|
|
30700
31841
|
openLattice2.register(
|
|
30701
31842
|
createAgentProvider2({
|
|
30702
31843
|
threadStore,
|
|
@@ -30719,18 +31860,29 @@ var start = async (config) => {
|
|
|
30719
31860
|
error: err instanceof Error ? err.message : String(err)
|
|
30720
31861
|
});
|
|
30721
31862
|
}
|
|
30722
|
-
|
|
30723
|
-
|
|
31863
|
+
try {
|
|
31864
|
+
const { registerGatewaySandboxOpenCredentialProvider: registerGatewaySandboxOpenCredentialProvider2 } = await Promise.resolve().then(() => (init_sandboxOpenCredentialProvider(), sandboxOpenCredentialProvider_exports));
|
|
31865
|
+
registerGatewaySandboxOpenCredentialProvider2((error) => {
|
|
31866
|
+
logger7.warn("sandbox open-credential provider failed", { error });
|
|
31867
|
+
});
|
|
31868
|
+
logger7.info("Sandbox open-credential provider registered");
|
|
31869
|
+
} catch (err) {
|
|
31870
|
+
logger7.warn("Sandbox open-credential provider unavailable", {
|
|
31871
|
+
error: err instanceof Error ? err.message : String(err)
|
|
31872
|
+
});
|
|
31873
|
+
}
|
|
31874
|
+
if (!import_core92.sandboxLatticeManager.hasLattice("default")) {
|
|
31875
|
+
import_core92.sandboxLatticeManager.registerLattice("default", getConfiguredSandboxProvider());
|
|
30724
31876
|
logger7.info("Registered sandbox manager from env configuration");
|
|
30725
31877
|
}
|
|
30726
31878
|
try {
|
|
30727
31879
|
const { ResourceController: ResourceController2 } = await Promise.resolve().then(() => (init_resources(), resources_exports));
|
|
30728
|
-
const sharedResourceStore = (0,
|
|
30729
|
-
const
|
|
31880
|
+
const sharedResourceStore = (0, import_core92.getStoreLattice)("default", "sharedResource").store;
|
|
31881
|
+
const cache2 = new import_core92.TokenCache();
|
|
30730
31882
|
const resourceController = new ResourceController2({
|
|
30731
31883
|
store: sharedResourceStore,
|
|
30732
|
-
sandboxManager:
|
|
30733
|
-
cache,
|
|
31884
|
+
sandboxManager: import_core92.sandboxLatticeManager,
|
|
31885
|
+
cache: cache2,
|
|
30734
31886
|
logger: logger7
|
|
30735
31887
|
});
|
|
30736
31888
|
registerResourceRoutes(app, resourceController);
|
|
@@ -30754,11 +31906,98 @@ var start = async (config) => {
|
|
|
30754
31906
|
}
|
|
30755
31907
|
}
|
|
30756
31908
|
const target_port = config?.port || Number(process.env.PORT) || 4001;
|
|
30757
|
-
|
|
30758
|
-
|
|
31909
|
+
(0, import_core92.configureCoordinationLeaseStore)((0, import_core92.getStoreLattice)("default", "lease").store);
|
|
31910
|
+
const outboxStore = (0, import_core92.getStoreLattice)("default", "outbox").store;
|
|
31911
|
+
import_core92.taskLifecycleNotifier.setOutbox(outboxStore);
|
|
31912
|
+
import_core92.projectTaskAdmissionNotifier.setOutbox(outboxStore);
|
|
31913
|
+
(0, import_core92.configurePluginCatalogSync)({ outbox: outboxStore, owner: (0, import_core92.getReplicaId)() });
|
|
31914
|
+
bridgeAssistantEvents(
|
|
31915
|
+
(event, cb) => import_core92.eventBus.subscribe(event, cb),
|
|
31916
|
+
outboxStore,
|
|
31917
|
+
(0, import_core92.getReplicaId)()
|
|
31918
|
+
);
|
|
31919
|
+
if (projectRoomRealtimeRuntime) {
|
|
31920
|
+
projectRoomRealtimeRuntime.broker.setBroadcastHook((scope, serialized, sourceKey) => {
|
|
31921
|
+
void publishRoomEvent(outboxStore, (0, import_core92.getReplicaId)(), scope, serialized, sourceKey);
|
|
31922
|
+
});
|
|
31923
|
+
}
|
|
31924
|
+
const outboxPoller = new import_core92.OutboxPoller({
|
|
31925
|
+
store: outboxStore,
|
|
31926
|
+
owner: (0, import_core92.getReplicaId)(),
|
|
31927
|
+
handlers: {
|
|
31928
|
+
"task-lifecycle": (payload) => import_core92.taskLifecycleNotifier.deliverFromOutbox(payload),
|
|
31929
|
+
"project-task-admission": (payload) => import_core92.projectTaskAdmissionNotifier.deliverFromOutbox(payload),
|
|
31930
|
+
[ROOM_EVENT_TOPIC]: async (payload) => {
|
|
31931
|
+
if (projectRoomRealtimeRuntime) ingestRoomEvent(payload, projectRoomRealtimeRuntime.broker);
|
|
31932
|
+
},
|
|
31933
|
+
"assistant-changed": (payload) => handleAssistantChanged(payload, (tenantId) => import_core92.agentLatticeManager.initializeStoredAssistantsForTenant(tenantId)),
|
|
31934
|
+
[MCP_CONFIG_CHANGED_TOPIC]: (payload) => reconcileMcpConfigChange(payload, {
|
|
31935
|
+
store: (0, import_core92.getStoreLattice)("default", "mcp").store,
|
|
31936
|
+
manager: import_core92.mcpManager,
|
|
31937
|
+
convertToConnection: import_core92.convertToConnection
|
|
31938
|
+
}),
|
|
31939
|
+
[import_core92.PLUGIN_CATALOG_CHANGED_TOPIC]: async (payload) => {
|
|
31940
|
+
const tenantId = payload?.tenantId;
|
|
31941
|
+
if (typeof tenantId === "string" && tenantId.length > 0) (0, import_core92.getSandboxPluginCatalog)().invalidate(tenantId);
|
|
31942
|
+
}
|
|
31943
|
+
},
|
|
31944
|
+
log: logger7
|
|
31945
|
+
});
|
|
31946
|
+
try {
|
|
31947
|
+
await outboxPoller.start();
|
|
31948
|
+
} catch (err) {
|
|
31949
|
+
logger7.warn("Outbox poller failed to start", { error: err instanceof Error ? err.message : String(err) });
|
|
31950
|
+
}
|
|
31951
|
+
const leaseStore = (0, import_core92.getStoreLattice)("default", "lease").store;
|
|
31952
|
+
if (leaseStore.constructor?.name === "InMemoryLeaseStore") {
|
|
31953
|
+
logger7.warn(
|
|
31954
|
+
"Startup recovery leader gate uses a non-distributed lease store (per-process only); configure a shared 'lease' store for multi-replica deployments",
|
|
31955
|
+
{ phase: "startup_recovery" }
|
|
31956
|
+
);
|
|
31957
|
+
}
|
|
31958
|
+
warnMultiReplicaReadiness(logger7);
|
|
31959
|
+
const startup = await (0, import_core92.runAsLeader)(leaseStore, "startup-recovery", async () => {
|
|
31960
|
+
if (routes.projectTaskRuntime) {
|
|
31961
|
+
await prepareProjectTaskRuntime(routes.projectTaskRuntime, logger7);
|
|
31962
|
+
}
|
|
31963
|
+
if (process.env.AXIOM_TASK_ORPHAN_RECOVERY === "true") {
|
|
31964
|
+
try {
|
|
31965
|
+
const { createOrphanRecoveryRuntime: createOrphanRecoveryRuntime2 } = await Promise.resolve().then(() => (init_OrphanRecoveryRuntime(), OrphanRecoveryRuntime_exports));
|
|
31966
|
+
const { createRecoveryCallerDeps: createRecoveryCallerDeps2 } = await Promise.resolve().then(() => (init_RecoveryCallerDeps(), RecoveryCallerDeps_exports));
|
|
31967
|
+
const runtime = createOrphanRecoveryRuntime2({
|
|
31968
|
+
taskStore: (0, import_core92.getStoreLattice)("default", "task").store,
|
|
31969
|
+
workItemStore: (0, import_core92.getStoreLattice)("default", "taskWorkItem").store,
|
|
31970
|
+
tenantStore: (0, import_core92.getStoreLattice)("default", "tenant").store,
|
|
31971
|
+
...createRecoveryCallerDeps2(),
|
|
31972
|
+
log: logger7
|
|
31973
|
+
});
|
|
31974
|
+
await runtime.recoverAll();
|
|
31975
|
+
} catch (err) {
|
|
31976
|
+
logger7.warn("Task orphan recovery failed", { error: err instanceof Error ? err.message : String(err) });
|
|
31977
|
+
}
|
|
31978
|
+
}
|
|
31979
|
+
if (import_core92.scheduleLatticeManager.hasLattice("default")) {
|
|
31980
|
+
try {
|
|
31981
|
+
const restored = await import_core92.scheduleLatticeManager.getScheduleLattice("default").restore();
|
|
31982
|
+
logger7.info("Scheduled tasks restored", { phase: "startup_recovery", restored });
|
|
31983
|
+
} catch (err) {
|
|
31984
|
+
logger7.warn("Scheduled task restore failed", {
|
|
31985
|
+
phase: "startup_recovery",
|
|
31986
|
+
error: err instanceof Error ? err.message : String(err)
|
|
31987
|
+
});
|
|
31988
|
+
}
|
|
31989
|
+
}
|
|
31990
|
+
}, { hold: true, ttlMs: 5 * 6e4 });
|
|
31991
|
+
if (!startup.ran) {
|
|
31992
|
+
logger7.info("Startup recovery skipped (another replica leads)", { phase: "startup_recovery" });
|
|
30759
31993
|
}
|
|
30760
31994
|
await app.listen({ port: target_port, host: "0.0.0.0" });
|
|
30761
31995
|
logger7.info(`Lattice Gateway is running on port: ${target_port}`);
|
|
31996
|
+
const outboxRetention = createOutboxRetentionJob({
|
|
31997
|
+
outbox: outboxStore,
|
|
31998
|
+
log: logger7
|
|
31999
|
+
});
|
|
32000
|
+
outboxRetention.start();
|
|
30762
32001
|
const queueServiceConfig = config?.queueServiceConfig;
|
|
30763
32002
|
if (queueServiceConfig) {
|
|
30764
32003
|
setQueueServiceType(queueServiceConfig.type);
|
|
@@ -30767,13 +32006,6 @@ var start = async (config) => {
|
|
|
30767
32006
|
agentTaskConsumer.startPollingQueue();
|
|
30768
32007
|
}
|
|
30769
32008
|
}
|
|
30770
|
-
if (process.env.AXIOM_RESTORE_PENDING_ON_STARTUP === "true") {
|
|
30771
|
-
import_core82.agentInstanceManager.restore().then((stats) => {
|
|
30772
|
-
logger7.info(`Agent recovery complete: ${stats.restored} threads restored, ${stats.errors} errors`);
|
|
30773
|
-
}).catch((error) => {
|
|
30774
|
-
logger7.error("Agent recovery failed", { error });
|
|
30775
|
-
});
|
|
30776
|
-
}
|
|
30777
32009
|
restoreMcpConnections().catch((error) => {
|
|
30778
32010
|
logger7.error("MCP connection restoration failed", { error });
|
|
30779
32011
|
});
|
|
@@ -30791,6 +32023,17 @@ var LatticeGateway = {
|
|
|
30791
32023
|
};
|
|
30792
32024
|
// Annotate the CommonJS export names for ESM import in node:
|
|
30793
32025
|
0 && (module.exports = {
|
|
30794
|
-
LatticeGateway
|
|
32026
|
+
LatticeGateway,
|
|
32027
|
+
ProjectRoomEventBroker,
|
|
32028
|
+
ROOM_EVENT_TOPIC,
|
|
32029
|
+
createOrphanRecoveryRuntime,
|
|
32030
|
+
createRecoveryCallerDeps,
|
|
32031
|
+
createTaskRunLiveness,
|
|
32032
|
+
ingestRoomEvent,
|
|
32033
|
+
publishRoomEvent,
|
|
32034
|
+
recoverTask,
|
|
32035
|
+
recoverTopCaller,
|
|
32036
|
+
resolveTopCaller,
|
|
32037
|
+
runOrphanRecovery
|
|
30795
32038
|
});
|
|
30796
32039
|
//# sourceMappingURL=index.js.map
|