feat(ai-workspace): add local relay profiles

This commit is contained in:
Codex
2026-06-20 12:54:19 +03:00
parent 2d5fef3948
commit 3526351b1b
28 changed files with 2959 additions and 77 deletions
@@ -44,6 +44,14 @@ const adapterPayload = {
const appGrants = normalizeEntitlementAdapterAppGrants(adapterPayload, adapter);
const mcpServers = runProfileMcpServersFromAppGrants({}, appGrants);
const appGrantSummary = summarizeRunAppGrants({ appGrants });
const assistantActions = {
schemaVersion: "ai-workspace.assistant-actions.v1",
endpoint: "/api/ai-workspace/hub/v1/assistant-relays/local-dev/actions",
gatewayUrl: "https://ai-hub.nodedc.ru/api/ai-workspace/hub/v1/assistant-relays/local-dev/actions",
gatewayToken: SECRET_TOKEN,
actionIds: ["hub.access_request.list_pending", "hub.user.read_admin_summary"],
phases: ["preview", "execute"],
};
const runProfile = {
schemaVersion: "ai-workspace.run-profile.v1",
runId: randomUUID(),
@@ -71,6 +79,7 @@ const runProfile = {
mcpServers,
mcpServerNames: mcpServers.map((server) => server.serverName),
requiredMcpServerNames: mcpServers.filter((server) => server.required).map((server) => server.serverName),
assistantActions,
},
diagnostics: {
schemaVersion: "ai-workspace.run-profile.diagnostics.v1",
@@ -106,6 +115,10 @@ assert.equal(publicProfile.toolProfile.mcpServers[0].serverName, "nodedc_ops_age
assert.equal(publicProfile.toolProfile.mcpServers[0].httpHeaders.Authorization, "<redacted>");
assert.equal(publicProfile.toolProfile.mcpServers[0].httpHeaders.Accept, "<redacted>");
assert.equal(publicProfile.toolProfile.mcpServers[0].headers, undefined);
assert.equal(publicProfile.toolProfile.assistantActions.endpoint, "/api/ai-workspace/hub/v1/assistant-relays/local-dev/actions");
assert.equal(publicProfile.toolProfile.assistantActions.gatewayUrl, "https://ai-hub.nodedc.ru/api/ai-workspace/hub/v1/assistant-relays/local-dev/actions");
assert.equal(publicProfile.toolProfile.assistantActions.gatewayToken, "<redacted>");
assert.deepEqual(publicProfile.toolProfile.assistantActions.actionIds, ["hub.access_request.list_pending", "hub.user.read_admin_summary"]);
assert.equal(JSON.stringify(publicProfile).includes(SECRET_TOKEN), false);
assert.match(runProfile.diagnostics.profileHash, /^[a-f0-9]{16}$/);
@@ -114,7 +127,9 @@ console.log(JSON.stringify({
checks: [
"adapter_grant_normalized",
"token_scoped_ops_mcp_in_run_profile",
"assistant_action_relay_in_run_profile",
"public_run_profile_redacts_mcp_headers",
"public_run_profile_redacts_assistant_action_gateway_token",
"stable_public_profile_hash",
],
mcpServerNames: runProfile.toolProfile.mcpServerNames,
@@ -276,6 +291,7 @@ function redactRunProfile(runProfile) {
appGrants: redactForPublicDiagnostics(runProfile.appGrants),
toolProfile: {
...(isPlainObject(runProfile.toolProfile) ? runProfile.toolProfile : {}),
assistantActions: redactAssistantActions(runProfile.toolProfile?.assistantActions),
mcpServers: Array.isArray(runProfile.toolProfile?.mcpServers)
? runProfile.toolProfile.mcpServers.map(redactMcpServer)
: [],
@@ -283,6 +299,14 @@ function redactRunProfile(runProfile) {
};
}
function redactAssistantActions(value) {
if (!isPlainObject(value)) return value;
return {
...value,
...(value.gatewayToken ? { gatewayToken: "<redacted>" } : {}),
};
}
function redactMcpServer(server) {
if (!isPlainObject(server)) return {};
const headers = isPlainObject(server.httpHeaders) ? server.httpHeaders : {};