godcrm/backend/routes/v3/ai-agents/sharedAgentResolution.js
GOD CRM Release f89e074dd1
Some checks failed
CI / Lint / Typecheck / Test / Build (push) Has been cancelled
CI / PostgreSQL Integration Tests (push) Has been cancelled
GOD CRM — public scrubbed snapshot
Governed substrate for autonomous agents: scoped identity (passports),
audited actions, MCP workspace. Infra IPs and secrets redacted for public release.
2026-08-10 04:01:45 +03:00

105 lines
3.6 KiB
JavaScript

/**
* Shared agent resolution helpers for CRUD controllers.
* Resolves model and provider references from row IDs to full data.
*/
import { dbGet } from '../../../database/connection.js';
import { safeParseJSON } from './shared.js';
/**
* Resolve a model reference (row ID or string) to model details.
*/
export async function resolveModel(modelRef) {
if (typeof modelRef === 'number') {
const modelRow = await dbGet(`
SELECT tr.data FROM table_rows tr
JOIN universal_tables ut ON tr.table_id = ut.id
WHERE tr.id = ? AND (ut.name LIKE '%Models%' OR ut.name LIKE '%models%')
`, [modelRef]);
if (modelRow) {
const modelData = safeParseJSON(modelRow.data, {});
return {
id: modelRef,
name: modelData.name || modelData.model_id,
model_id: modelData.model_id || modelData.api_id || 'gpt-4o'
};
}
}
return { id: null, name: modelRef, model_id: modelRef || 'gpt-4o' };
}
/**
* Resolve a provider/operator reference (row ID or string) to provider details.
*/
export async function resolveProvider(providerRef) {
if (typeof providerRef === 'number') {
const providerRow = await dbGet(`
SELECT tr.data FROM table_rows tr
JOIN universal_tables ut ON tr.table_id = ut.id
WHERE tr.id = ? AND (ut.name LIKE '%Operators%' OR ut.name LIKE '%Providers%')
`, [providerRef]);
if (providerRow) {
const providerData = safeParseJSON(providerRow.data, {});
return {
id: providerRef,
name: providerData.name,
api_identifier: (providerData.provider || providerData.api_identifier || providerData.name || 'openai').toLowerCase()
};
}
}
return { id: null, name: providerRef, api_identifier: providerRef || 'openai' };
}
/**
* Parse agent row data into a standardized agent object.
*/
export function parseAgentRow(row, data, extra = {}) {
let tools = [];
if (data.tools) {
try {
tools = typeof data.tools === 'string' ? safeParseJSON(data.tools, {}) : data.tools;
} catch (e) {
tools = [];
}
}
let tags = [];
if (data.tags) {
try {
tags = typeof data.tags === 'string' ? safeParseJSON(data.tags, []) : (Array.isArray(data.tags) ? data.tags : []);
} catch (e) {
tags = [];
}
}
const isActive = data.is_active === true || data.is_active === 1 ||
data.is_active === 'true' || data.is_active === '1' || data.status === 'active';
return {
id: row.id,
name: data.name || data.agent_name || 'Unnamed Agent',
description: data.description || '',
system_prompt: data.system_prompt || '',
icon: data.icon || data.avatar || '🤖',
color: data.color || '#3B82F6',
is_active: isActive,
api_key_id: data.api_key_id || null,
tools,
tags,
operator_id: data.operator_id,
status: data.status || 'active',
response_mode: data.response_mode || 'mention_only',
// ADR-0057 — surface invocation_mode and main_instructions to clients so
// the edit modal can show current state. Both default to null and are
// tolerant of missing keys (legacy rows pre-ADR-0057).
invocation_mode: data.invocation_mode || null,
main_instructions: data.main_instructions ?? data.main_instruction ?? null,
tables_config: data.tables_config || null,
context_settings: data.context_settings || null,
// ADR-0079: surface agent_slug + visibility so frontend agentVisibility filter
// and the promo-unlock merge below in agentCrudController can both run.
agent_slug: data.agent_slug || data.slug || null,
visibility: data.visibility || 'default',
...extra
};
}