Skip to content
Merged
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
5 changes: 4 additions & 1 deletion backend/actions/ChatMessage/executeScript.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,10 @@ module.exports = ({ db, studioConnection }) => async function executeScript(para

// Create a sandbox with the db object
const logs = [];
const sandbox = { db, console: {}, ObjectId: mongoose.Types.ObjectId };
if (!db.Types) {
db.Types = mongoose.Types;
}
const sandbox = { db, mongoose, console: {}, ObjectId: mongoose.Types.ObjectId };
Comment on lines +42 to +45
Copy link

Copilot AI Jan 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mutating the db object by adding Types to it could have unintended side effects if the same db object is reused across multiple script executions or in other parts of the application. Consider adding Types directly to the sandbox object instead, or document that this is intentional behavior. For example: sandbox.db = Object.assign({}, db, { Types: mongoose.Types }) or add a separate Types property to the sandbox.

Suggested change
if (!db.Types) {
db.Types = mongoose.Types;
}
const sandbox = { db, mongoose, console: {}, ObjectId: mongoose.Types.ObjectId };
const sandboxDb = db && typeof db === 'object' ?
Object.assign({}, db, { Types: db.Types || mongoose.Types }) :
{ Types: mongoose.Types };
const sandbox = { db: sandboxDb, mongoose, console: {}, ObjectId: mongoose.Types.ObjectId };

Copilot uses AI. Check for mistakes.

// Capture console logs
sandbox.console.log = function() {
Expand Down
50 changes: 28 additions & 22 deletions backend/actions/ChatThread/createChatMessage.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,42 +101,48 @@ module.exports = ({ db, studioConnection, options }) => async function createCha
};

const systemPrompt = `
You are a data querying assistant who writes scripts for users accessing MongoDB data using Node.js and Mongoose.
You are a data querying assistant who writes scripts for users accessing MongoDB data using Node.js and Mongoose.

Keep scripts concise. Avoid unnecessary comments, error handling, and temporary variables.
The following globals are available. Assume no other globals exist.
- db: The Mongoose connection object or Mongoose singleton depending on what the user passed in
- mongoose: the output of require('mongoose').
- ObjectId: MongoDB ObjectId class from mongoose.Types.ObjectId
- console: has a stubbed log() function that logs to the console and is accessible in the output.

Do not write any imports or require() statements, that will cause the script to break.
Keep scripts concise. Avoid unnecessary comments, error handling, and temporary variables.

If the user approves the script, the script will run in the Node.js server in a sandboxed vm.createContext() call with only 1 global variable: db, which contains the Mongoose connection. The script return value will then send the response via JSON to the client. Be aware that the result of the query will be serialized to JSON before being displayed to the user. MAKE SURE TO RETURN A VALUE FROM THE SCRIPT.
Do not write any imports or require() statements, that will cause the script to break.

Optimize scripts for readability first, followed by reliability, followed by performance. Avoid using the aggregation framework unless explicitly requested by the user. Use indexed fields in queries where possible.
If the user approves the script, the script will run in the Node.js server in a sandboxed vm.createContext() call with only 1 global variable: db, which contains the Mongoose connection. The script return value will then send the response via JSON to the client. Be aware that the result of the query will be serialized to JSON before being displayed to the user. MAKE SURE TO RETURN A VALUE FROM THE SCRIPT.
Copy link

Copilot AI Jan 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This statement is now inaccurate. The prompt earlier documents 4 available globals (db, mongoose, ObjectId, console), but this line still says "only 1 global variable: db". This should be updated to reflect the actual number of globals available in the sandbox, or this entire sentence could be reworded to remove the specific count.

Suggested change
If the user approves the script, the script will run in the Node.js server in a sandboxed vm.createContext() call with only 1 global variable: db, which contains the Mongoose connection. The script return value will then send the response via JSON to the client. Be aware that the result of the query will be serialized to JSON before being displayed to the user. MAKE SURE TO RETURN A VALUE FROM THE SCRIPT.
If the user approves the script, the script will run in the Node.js server in a sandboxed vm.createContext() call with only the following global variables available: db, mongoose, ObjectId, and console. The script return value will then send the response via JSON to the client. Be aware that the result of the query will be serialized to JSON before being displayed to the user. MAKE SURE TO RETURN A VALUE FROM THE SCRIPT.

Copilot uses AI. Check for mistakes.

Assume the user has pre-defined schemas and models. Do not define any new schemas or models for the user.
Optimize scripts for readability first, followed by reliability, followed by performance. Avoid using the aggregation framework unless explicitly requested by the user. Use indexed fields in queries where possible.

Use async/await where possible. Assume top-level await is allowed.
Assume the user has pre-defined schemas and models. Do not define any new schemas or models for the user.

Write at most one script, unless the user explicitly asks for multiple scripts.
Use async/await where possible. Assume top-level await is allowed.

Think carefully about the user's input and identify the models referred to by the user's query.
Write at most one script, unless the user explicitly asks for multiple scripts.

Format output as Markdown, including code fences for any scripts the user requested.
Think carefully about the user's input and identify the models referred to by the user's query.

Add a brief text description of what the script does.
Format output as Markdown, including code fences for any scripts the user requested.

If the user's query is best answered with a chart, return a Chart.js 4 configuration as \`return { $chart: chartJSConfig };\`. Disable ChartJS animation by default unless user asks for it. Set responsive: true, maintainAspectRatio: false options unless the user explicitly asks.
Add a brief text description of what the script does.

If the user\'s query is best answered by a map, return an object { $featureCollection } which contains a GeoJSON FeatureCollection
If the user's query is best answered with a chart, return a Chart.js 4 configuration as \`return { $chart: chartJSConfig };\`. Disable ChartJS animation by default unless user asks for it. Set responsive: true, maintainAspectRatio: false options unless the user explicitly asks.

Example output:
If the user\'s query is best answered by a map, return an object { $featureCollection } which contains a GeoJSON FeatureCollection

The following script counts the number of users which are not deleted.
Example output:

\`\`\`javascript
const users = await db.model('User').find({ isDeleted: false });
return { numUsers: users.length };
\`\`\`
The following script counts the number of users which are not deleted.

-----------
\`\`\`javascript
const users = await db.model('User').find({ isDeleted: false });
return { numUsers: users.length };
\`\`\`

Here is a description of the user's models. Assume these are the only models available in the system unless explicitly instructed otherwise by the user.
`.trim();
-----------

Here is a description of the user's models. Assume these are the only models available in the system unless explicitly instructed otherwise by the user.
`.trim();