Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
210 changes: 210 additions & 0 deletions migrations/mongo/20260409224600-agent_info_migration.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
/**
* @param db {import('mongodb').Db}
* @param client {import('mongodb').MongoClient}
* @returns {Promise<void>}
*/
export const up = async (db) => {
console.log("Starting agent_info field migration...");

// Process configurations collection (includes availability from page_config)
await migrateCollection(db, "configurations", true);

// Process configuration_versions collection (no availability)
await migrateCollection(db, "configuration_versions", false);

console.log("Agent_info field migration completed successfully!");
};

/**
* @param db {import('mongodb').Db}
* @param client {import('mongodb').MongoClient}
* @returns {Promise<void>}
*/
export const down = async (db) => {
console.log("Rolling back agent_info field migration...");

// Rollback configurations collection
await rollbackCollection(db, "configurations", true);

// Rollback configuration_versions collection
await rollbackCollection(db, "configuration_versions", false);

console.log("Agent_info field rollback completed successfully!");
};

async function migrateCollection(db, collectionName, includeAvailability) {
console.log(`\nProcessing ${collectionName} collection...`);

const collection = db.collection(collectionName);

// Find ALL documents in the collection
const documents = await collection.find({}).toArray();
console.log(`Found ${documents.length} total documents in ${collectionName}`);

if (documents.length === 0) {
console.log(`No documents found in ${collectionName}`);
return;
}

// Process in batches
const batchSize = 100;
let processedCount = 0;

for (let i = 0; i < documents.length; i += batchSize) {
const batch = documents.slice(i, i + batchSize);
const bulkOps = [];

for (const doc of batch) {
// Build the agent_info object with defaults and existing values
const agent_info = {};

// Add prompt_total_tokens with default if missing
agent_info.prompt_total_tokens = doc.prompt_total_tokens || 0;

// Add availability from page_config (only for configurations) with default
if (includeAvailability) {
agent_info.availability = doc.page_config?.availability || "private";
}

// Add connected_agent_details with default if missing
agent_info.connected_agent_details = doc.connected_agent_details || {};

// Add variables_state with default if missing
agent_info.variables_state = doc.variables_state || {};

// Create update operation
const updateOp = {
updateOne: {
filter: { _id: doc._id },
update: {
$set: {
agent_info: agent_info
}
}
}
};

// Add $unset for old fields that were moved (only if they existed)
const unsetFields = {};
if (doc.prompt_total_tokens !== undefined) {
unsetFields.prompt_total_tokens = 1;
}
if (doc.connected_agent_details !== undefined) {
unsetFields.connected_agent_details = 1;
}
if (doc.variables_state !== undefined) {
unsetFields.variables_state = 1;
}

// For configurations, also remove availability from page_config if it existed
if (includeAvailability && doc.page_config?.availability !== undefined) {
unsetFields["page_config.availability"] = 1;
}

if (Object.keys(unsetFields).length > 0) {
updateOp.updateOne.update.$unset = unsetFields;
}

bulkOps.push(updateOp);
}

// Execute batch update
if (bulkOps.length > 0) {
const result = await collection.bulkWrite(bulkOps);
processedCount += result.modifiedCount;
console.log(
`Processed batch ${Math.floor(i / batchSize) + 1}/${Math.ceil(documents.length / batchSize)}: ${result.modifiedCount} documents updated`
);
}
}

console.log(`Completed ${collectionName}: ${processedCount} documents updated`);

// Verify migration - all documents should now have agent_info field
const missingAgentInfoDocs = await collection.countDocuments({ agent_info: { $exists: false } });
if (missingAgentInfoDocs === 0) {
console.log(`Verification passed: All documents in ${collectionName} now have agent_info field`);
} else {
console.log(`Verification warning: ${missingAgentInfoDocs} documents in ${collectionName} still missing agent_info field`);
}

// Check agent_info field count
const agentInfoDocs = await collection.countDocuments({ agent_info: { $exists: true } });
console.log(`${collectionName} now has ${agentInfoDocs} documents with agent_info field`);
}

async function rollbackCollection(db, collectionName, includeAvailability) {
console.log(`\nRolling back ${collectionName} collection...`);

const collection = db.collection(collectionName);

// Find all documents with agent_info field
const documents = await collection.find({ agent_info: { $exists: true } }).toArray();
console.log(`Found ${documents.length} documents with agent_info in ${collectionName}`);

if (documents.length === 0) {
console.log(`No documents with agent_info found in ${collectionName}`);
return;
}

// Process in batches
const batchSize = 100;
let processedCount = 0;

for (let i = 0; i < documents.length; i += batchSize) {
const batch = documents.slice(i, i + batchSize);
const bulkOps = [];

for (const doc of batch) {
const agent_info = doc.agent_info || {};
const setFields = {};
const unsetFields = { agent_info: 1 };

// Restore prompt_total_tokens if it exists in agent_info
if (agent_info.prompt_total_tokens !== undefined) {
setFields.prompt_total_tokens = agent_info.prompt_total_tokens;
}

// Restore connected_agent_details if it exists in agent_info
if (agent_info.connected_agent_details !== undefined) {
setFields.connected_agent_details = agent_info.connected_agent_details;
}

// Restore variables_state if it exists in agent_info
if (agent_info.variables_state !== undefined) {
setFields.variables_state = agent_info.variables_state;
}

// Restore availability to page_config for configurations
if (includeAvailability && agent_info.availability !== undefined) {
setFields["page_config.availability"] = agent_info.availability;
}

const updateOp = {
updateOne: {
filter: { _id: doc._id },
update: {}
}
};

if (Object.keys(setFields).length > 0) {
updateOp.updateOne.update.$set = setFields;
}

updateOp.updateOne.update.$unset = unsetFields;

bulkOps.push(updateOp);
}

// Execute batch update
if (bulkOps.length > 0) {
const result = await collection.bulkWrite(bulkOps);
processedCount += result.modifiedCount;
console.log(
`Rolled back batch ${Math.floor(i / batchSize) + 1}/${Math.ceil(documents.length / batchSize)}: ${result.modifiedCount} documents updated`
);
}
}

console.log(`Completed rollback for ${collectionName}: ${processedCount} documents updated`);
}
10 changes: 7 additions & 3 deletions src/controllers/agentConfig.controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -276,8 +276,13 @@ const updateAgentController = async (req, res, next) => {
}
}

if (body.connected_agent_details) {
update_fields.connected_agent_details = body.connected_agent_details;
// Handle agent_info updates
if (body.agent_info) {
const filteredAgentInfo = Object.fromEntries(Object.entries(body.agent_info).filter(([, value]) => value !== undefined));
update_fields.agent_info = {
...update_fields.agent_info,
...filteredAgentInfo
};
}

if (body.apikey_object_id) {
Expand Down Expand Up @@ -311,7 +316,6 @@ const updateAgentController = async (req, res, next) => {
"gpt_memory",
"gpt_memory_context",
"doc_ids",
"variables_state",
"IsstarterQuestionEnable",
Comment thread
Anushtha-Rathore marked this conversation as resolved.
"name",
"bridgeType",
Expand Down
9 changes: 4 additions & 5 deletions src/controllers/template.controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ const FILTER_BRIDGE_EXCLUDE_KEYS = new Set([
"org_id",
"user_id",
"total_tokens",
"prompt_total_tokens",
"prompt_enhancer_percentage",
"bridge_usage",
"bridge_limit",
Expand Down Expand Up @@ -214,7 +213,7 @@ const createAgentFromTemplateController = async (req, res, next) => {

const fall_back = template_content?.settings?.fall_back || { is_enable: true, service: "openai", model: "gpt-5.1" };
const template_fields = [
"variables_state",
"agent_info",
"built_in_tools",
"gpt_memory_context",
"user_reference",
Expand All @@ -230,7 +229,6 @@ const createAgentFromTemplateController = async (req, res, next) => {
"settings",
"criteria_check",
"auto_model_select",
"connected_agent_details",
"meta",
"cache_on",
"chatbot_auto_answers",
Expand Down Expand Up @@ -456,8 +454,9 @@ const createAgentFromTemplateController = async (req, res, next) => {
if (child_function_ids_resolved) child_updates.function_ids = child_function_ids_resolved;
const child_pre_tools = resolvePreTools(child_details.pre_tools);
if (child_pre_tools) child_updates.pre_tools = child_pre_tools;
if (child_details.connected_agent_details && Object.keys(child_details.connected_agent_details).length > 0) {
child_updates.connected_agent_details = child_details.connected_agent_details;
if (child_details.agent_info?.connected_agent_details && Object.keys(child_details.agent_info.connected_agent_details).length > 0) {
child_updates.agent_info = child_updates.agent_info || {};
child_updates.agent_info.connected_agent_details = child_details.agent_info.connected_agent_details;
Comment thread
Anushtha-Rathore marked this conversation as resolved.
}
const child_doc_ids = resolveDocIds(child_details.doc_ids);
if (child_doc_ids) child_updates.doc_ids = child_doc_ids;
Expand Down
11 changes: 6 additions & 5 deletions src/db_services/agentVersion.service.js
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ async function calculateAndSavePromptTokens(parentId, prompt, tools) {
const promptTotalTokens = promptTokens + toolsTokens;

// Update the document in the configurationModel
await configurationModel.updateOne({ _id: parentId }, { $set: { prompt_total_tokens: promptTotalTokens } });
await configurationModel.updateOne({ _id: parentId }, { $set: { "agent_info.prompt_total_tokens": promptTotalTokens } });

return promptTotalTokens;
} catch (error) {
Expand Down Expand Up @@ -397,7 +397,7 @@ async function publish(org_id, version_id, user_id) {

// Extract agent variables logic
const prompt = convertPromptToString(getVersionData.configuration?.prompt || "");
const variableState = getVersionData.variables_state || {};
const variableState = getVersionData.agent_info?.variables_state || {};
const variablePath = getVersionData.variables_path || {};

if (Array.isArray(getVersionData.pre_tools)) {
Expand Down Expand Up @@ -430,8 +430,9 @@ async function publish(org_id, version_id, user_id) {
}

// Update connected_agent_details with agent variables
updatedConfiguration.connected_agent_details = {
...(updatedConfiguration.connected_agent_details || {}),
updatedConfiguration.agent_info = updatedConfiguration.agent_info || {};
updatedConfiguration.agent_info.connected_agent_details = {
...(updatedConfiguration.agent_info.connected_agent_details || {}),
agent_variables: {
fields: transformedAgentVariables.fields,
required_params: transformedAgentVariables.required_params
Expand Down Expand Up @@ -529,7 +530,7 @@ async function getAllConnectedAgents(id, org_id, type) {
}

const agentName = doc.name || `Agent_${agentId}`;
const connectedAgentDetails = doc.connected_agent_details || {};
const connectedAgentDetails = doc.agent_info?.connected_agent_details || {};
const threadId = connectedAgentDetails.thread_id || false;
const description = connectedAgentDetails.description;

Expand Down
Loading