feat(map): add persistent gateway and ontology package

This commit is contained in:
Codex
2026-07-13 17:14:34 +03:00
parent d196d4b0c7
commit e527812826
21 changed files with 1323 additions and 9 deletions
+51 -9
View File
@@ -271,8 +271,9 @@ app.post("/api/ai-workspace/assistant/v1/actions", requireInternalApi, asyncRout
app.get("/api/ai-workspace/assistant/v1/executors", requireInternalApi, asyncRoute(async (req, res) => {
const owner = getRequestOwner(req);
const visibility = sanitizeExecutorVisibility(req.query.visibility || req.query.executorVisibility || req.query.executor_visibility || "interactive");
const [executors, settings] = await Promise.all([
listExecutors(owner),
listExecutors(owner, { visibility }),
getOwnerSettings(owner),
]);
res.json({ ok: true, owner: publicOwner(owner), selectedExecutorId: settings.selectedExecutorId, settings: publicOwnerSettings(settings), executors });
@@ -692,7 +693,17 @@ httpServer.listen(config.port, "0.0.0.0", () => {
process.on("SIGTERM", shutdown);
process.on("SIGINT", shutdown);
async function listExecutors(owner) {
function executorVisibility(executor) {
const metadata = isPlainObject(executor?.metadata) ? executor.metadata : {};
const explicitVisibility = normalizeKey(metadata.visibility || metadata.executorVisibility);
if (explicitVisibility === "service" || explicitVisibility === "interactive") return explicitVisibility;
const appId = normalizeKey(metadata.appId || metadata.app_id);
const modeId = normalizeKey(metadata.modeId || metadata.mode_id);
if (appId === "seo-mode" || modeId === "seo-model-task") return "service";
return "interactive";
}
async function listExecutors(owner, { visibility = "all" } = {}) {
const result = await pool.query(
`select *
from ai_workspace_executors
@@ -700,7 +711,10 @@ async function listExecutors(owner) {
order by updated_at desc, created_at desc`,
[owner.key]
);
return Promise.all(result.rows.map((row) => decorateExecutorLiveStatus(toExecutor(row))));
const executors = result.rows.map(toExecutor).filter((executor) => (
visibility === "all" || executorVisibility(executor) === visibility
));
return Promise.all(executors.map(decorateExecutorLiveStatus));
}
async function decorateExecutorLiveStatus(executor) {
@@ -1557,7 +1571,11 @@ async function readExecutorEvents(executor, options = {}) {
10000
);
return {
events: Array.isArray(payload.events) ? payload.events.map(cleanBridgeEventForUi) : [],
events: Array.isArray(payload.events)
? payload.events.map((event) => cleanBridgeEventForUi(event, {
preserveLegacyCodexOutput: options.preserveLegacyCodexOutput === true,
}))
: [],
latestEventId: Number(payload.latestEventId || 0),
online: payload.online === true,
};
@@ -1898,6 +1916,7 @@ async function mirrorBridgeRunOnce(state) {
const payload = await readExecutorEvents(state.executor, {
since: state.latestEventId,
limit: 500,
preserveLegacyCodexOutput: true,
});
state.latestEventId = Math.max(state.latestEventId, Number(payload.latestEventId || 0));
const nextEvents = (Array.isArray(payload.events) ? payload.events : [])
@@ -3081,7 +3100,7 @@ function bridgeCompatibilityStatus(health, agent) {
};
}
function cleanBridgeEventForUi(event) {
function cleanBridgeEventForUi(event, options = {}) {
if (!isPlainObject(event)) return event;
const kind = optionalString(event.kind) || "";
const text = optionalString(event.text || event.message) || "";
@@ -3093,7 +3112,9 @@ function cleanBridgeEventForUi(event) {
};
}
if (kind !== "stdout" && kind !== "stderr") return event;
const cleaned = summarizeLegacyCodexEventText(text);
const cleaned = summarizeLegacyCodexEventText(text, {
preserveCodexOutput: options.preserveLegacyCodexOutput === true,
});
if (!cleaned || cleaned === text) return event;
return {
...event,
@@ -3103,12 +3124,14 @@ function cleanBridgeEventForUi(event) {
};
}
function summarizeLegacyCodexEventText(value) {
function summarizeLegacyCodexEventText(value, options = {}) {
const text = optionalString(value) || "";
if (!text) return "";
if (/^codex\s*\n/i.test(text)) {
const answer = text.replace(/^codex\s*\n/i, "").trim();
return answer ? `Codex emitted assistant output: ${answer.slice(0, 1200)}` : "Codex emitted assistant output.";
if (!answer) return "Codex emitted assistant output.";
const maxLength = options.preserveCodexOutput ? 250000 : 1200;
return `Codex emitted assistant output: ${answer.slice(0, maxLength)}`;
}
if (/^tokens used/im.test(text)) return "Tokens reported.";
return text.length > 1200 ? `${text.slice(0, 1200).trim()}...` : text;
@@ -3139,8 +3162,21 @@ async function listThreads(owner, { surface, kind = "all", limit, includeArchive
}
if (kind === "shared") {
clauses.push("coalesce(active_context->>'modeId', '') <> 'codex-remote'");
clauses.push(`not (
coalesce(metadata->>'visibility', '') = 'service'
or origin_surface = 'seo-mode'
or coalesce(active_context->>'modeId', '') = 'seo-model-task'
or coalesce(metadata->>'threadKind', '') = 'model-task'
)`);
} else if (kind === "remote") {
clauses.push("active_context->>'modeId' = 'codex-remote'");
} else if (kind === "service") {
clauses.push(`(
coalesce(metadata->>'visibility', '') = 'service'
or origin_surface = 'seo-mode'
or coalesce(active_context->>'modeId', '') = 'seo-model-task'
or coalesce(metadata->>'threadKind', '') = 'model-task'
)`);
}
const result = await pool.query(
`select *
@@ -3653,10 +3689,16 @@ function sanitizeBridgeDispatchCommand(payload) {
function sanitizeThreadKind(value) {
const text = normalizeKey(value || "all");
if (text === "shared" || text === "remote" || text === "all") return text;
if (text === "shared" || text === "remote" || text === "service" || text === "all") return text;
return "all";
}
function sanitizeExecutorVisibility(value) {
const text = normalizeKey(value || "interactive");
if (text === "interactive" || text === "service" || text === "all") return text;
return "interactive";
}
function sanitizeBridgeStopCommand(payload) {
const source = isPlainObject(payload) ? payload : {};
return {