@intranefr/superbackend 1.5.2 → 1.5.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +2 -0
- package/manage.js +745 -0
- package/package.json +4 -2
- package/src/controllers/admin.controller.js +11 -5
- package/src/controllers/adminAgents.controller.js +37 -0
- package/src/controllers/adminLlm.controller.js +19 -0
- package/src/controllers/adminMarkdowns.controller.js +157 -0
- package/src/controllers/adminScripts.controller.js +138 -0
- package/src/controllers/adminTelegram.controller.js +72 -0
- package/src/controllers/markdowns.controller.js +42 -0
- package/src/helpers/mongooseHelper.js +6 -6
- package/src/helpers/scriptBase.js +2 -2
- package/src/middleware.js +136 -29
- package/src/models/Agent.js +105 -0
- package/src/models/AgentMessage.js +82 -0
- package/src/models/Markdown.js +75 -0
- package/src/models/ScriptRun.js +8 -0
- package/src/models/TelegramBot.js +42 -0
- package/src/routes/adminAgents.routes.js +13 -0
- package/src/routes/adminLlm.routes.js +1 -0
- package/src/routes/adminMarkdowns.routes.js +16 -0
- package/src/routes/adminScripts.routes.js +4 -1
- package/src/routes/adminTelegram.routes.js +14 -0
- package/src/routes/markdowns.routes.js +16 -0
- package/src/services/agent.service.js +546 -0
- package/src/services/agentHistory.service.js +345 -0
- package/src/services/agentTools.service.js +578 -0
- package/src/services/jsonConfigs.service.js +22 -10
- package/src/services/llm.service.js +219 -6
- package/src/services/markdowns.service.js +522 -0
- package/src/services/scriptsRunner.service.js +328 -37
- package/src/services/telegram.service.js +130 -0
- package/views/admin-agents.ejs +273 -0
- package/views/admin-coolify-deploy.ejs +8 -8
- package/views/admin-dashboard.ejs +36 -5
- package/views/admin-experiments.ejs +1 -1
- package/views/admin-markdowns.ejs +905 -0
- package/views/admin-scripts.ejs +221 -4
- package/views/admin-telegram.ejs +269 -0
- package/views/partials/dashboard/nav-items.ejs +3 -0
- package/analysis-only.skill +0 -0
package/src/middleware.js
CHANGED
|
@@ -161,6 +161,8 @@ function createMiddleware(options = {}) {
|
|
|
161
161
|
maxPoolSize: 10,
|
|
162
162
|
};
|
|
163
163
|
|
|
164
|
+
const telegramService = require("./services/telegram.service");
|
|
165
|
+
|
|
164
166
|
// Return a promise that resolves when connection is established
|
|
165
167
|
const connectionPromise = mongoose
|
|
166
168
|
.connect(mongoUri, connectionOptions)
|
|
@@ -173,6 +175,9 @@ function createMiddleware(options = {}) {
|
|
|
173
175
|
await blogCronsBootstrap.bootstrap();
|
|
174
176
|
await require("./services/experimentsCronsBootstrap.service").bootstrap();
|
|
175
177
|
|
|
178
|
+
// Initialize Telegram bots
|
|
179
|
+
await telegramService.init();
|
|
180
|
+
|
|
176
181
|
// Console manager is already initialized early in the middleware
|
|
177
182
|
console.log("[Console Manager] MongoDB connection established");
|
|
178
183
|
|
|
@@ -658,36 +663,98 @@ function createMiddleware(options = {}) {
|
|
|
658
663
|
});
|
|
659
664
|
});
|
|
660
665
|
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
666
|
+
router.get(`${adminPath}/db-browser`, basicAuth, (req, res) => {
|
|
667
|
+
const templatePath = path.join(
|
|
668
|
+
__dirname,
|
|
669
|
+
"..",
|
|
670
|
+
"views",
|
|
671
|
+
"admin-db-browser.ejs",
|
|
672
|
+
);
|
|
673
|
+
fs.readFile(templatePath, "utf8", (err, template) => {
|
|
674
|
+
if (err) {
|
|
675
|
+
console.error("Error reading template:", err);
|
|
676
|
+
return res.status(500).send("Error loading page");
|
|
677
|
+
}
|
|
678
|
+
try {
|
|
679
|
+
const html = ejs.render(
|
|
680
|
+
template,
|
|
681
|
+
{
|
|
682
|
+
baseUrl: req.baseUrl,
|
|
683
|
+
adminPath,
|
|
684
|
+
},
|
|
685
|
+
{
|
|
686
|
+
filename: templatePath,
|
|
687
|
+
},
|
|
688
|
+
);
|
|
689
|
+
res.send(html);
|
|
690
|
+
} catch (renderErr) {
|
|
691
|
+
console.error("Error rendering template:", renderErr);
|
|
692
|
+
res.status(500).send("Error rendering page");
|
|
693
|
+
}
|
|
694
|
+
});
|
|
695
|
+
});
|
|
696
|
+
|
|
697
|
+
router.get(`${adminPath}/telegram`, basicAuth, (req, res) => {
|
|
698
|
+
const templatePath = path.join(
|
|
699
|
+
__dirname,
|
|
700
|
+
"..",
|
|
701
|
+
"views",
|
|
702
|
+
"admin-telegram.ejs",
|
|
703
|
+
);
|
|
704
|
+
fs.readFile(templatePath, "utf8", (err, template) => {
|
|
705
|
+
if (err) {
|
|
706
|
+
console.error("Error reading template:", err);
|
|
707
|
+
return res.status(500).send("Error loading page");
|
|
708
|
+
}
|
|
709
|
+
try {
|
|
710
|
+
const html = ejs.render(
|
|
711
|
+
template,
|
|
712
|
+
{
|
|
713
|
+
baseUrl: req.baseUrl,
|
|
714
|
+
adminPath,
|
|
715
|
+
},
|
|
716
|
+
{
|
|
717
|
+
filename: templatePath,
|
|
718
|
+
},
|
|
719
|
+
);
|
|
720
|
+
res.send(html);
|
|
721
|
+
} catch (renderErr) {
|
|
722
|
+
console.error("Error rendering template:", renderErr);
|
|
723
|
+
res.status(500).send("Error rendering page");
|
|
724
|
+
}
|
|
725
|
+
});
|
|
726
|
+
});
|
|
727
|
+
|
|
728
|
+
router.get(`${adminPath}/agents`, basicAuth, (req, res) => {
|
|
729
|
+
const templatePath = path.join(
|
|
730
|
+
__dirname,
|
|
731
|
+
"..",
|
|
732
|
+
"views",
|
|
733
|
+
"admin-agents.ejs",
|
|
734
|
+
);
|
|
735
|
+
fs.readFile(templatePath, "utf8", (err, template) => {
|
|
736
|
+
if (err) {
|
|
737
|
+
console.error("Error reading template:", err);
|
|
738
|
+
return res.status(500).send("Error loading page");
|
|
739
|
+
}
|
|
740
|
+
try {
|
|
741
|
+
const html = ejs.render(
|
|
742
|
+
template,
|
|
743
|
+
{
|
|
744
|
+
baseUrl: req.baseUrl,
|
|
745
|
+
adminPath,
|
|
746
|
+
},
|
|
747
|
+
{
|
|
748
|
+
filename: templatePath,
|
|
749
|
+
},
|
|
750
|
+
);
|
|
751
|
+
res.send(html);
|
|
752
|
+
} catch (renderErr) {
|
|
753
|
+
console.error("Error rendering template:", renderErr);
|
|
754
|
+
res.status(500).send("Error rendering page");
|
|
755
|
+
}
|
|
756
|
+
});
|
|
689
757
|
});
|
|
690
|
-
});
|
|
691
758
|
|
|
692
759
|
router.use("/api/admin", require("./routes/admin.routes"));
|
|
693
760
|
router.use("/api/admin/settings", require("./routes/globalSettings.routes"));
|
|
@@ -699,6 +766,10 @@ function createMiddleware(options = {}) {
|
|
|
699
766
|
"/api/admin/json-configs",
|
|
700
767
|
require("./routes/adminJsonConfigs.routes"),
|
|
701
768
|
);
|
|
769
|
+
router.use(
|
|
770
|
+
"/api/admin/markdowns",
|
|
771
|
+
require("./routes/adminMarkdowns.routes"),
|
|
772
|
+
);
|
|
702
773
|
router.use(
|
|
703
774
|
"/api/admin/rate-limits",
|
|
704
775
|
require("./routes/adminRateLimits.routes"),
|
|
@@ -748,6 +819,8 @@ function createMiddleware(options = {}) {
|
|
|
748
819
|
require("./routes/adminAudit.routes"),
|
|
749
820
|
);
|
|
750
821
|
router.use("/api/admin/llm", require("./routes/adminLlm.routes"));
|
|
822
|
+
router.use("/api/admin/telegram", require("./routes/adminTelegram.routes"));
|
|
823
|
+
router.use("/api/admin/agents", require("./routes/adminAgents.routes"));
|
|
751
824
|
router.use(
|
|
752
825
|
"/api/admin/ejs-virtual",
|
|
753
826
|
require("./routes/adminEjsVirtual.routes"),
|
|
@@ -762,6 +835,7 @@ function createMiddleware(options = {}) {
|
|
|
762
835
|
router.use("/api/settings", require("./routes/globalSettings.routes"));
|
|
763
836
|
router.use("/api/feature-flags", require("./routes/featureFlags.routes"));
|
|
764
837
|
router.use("/api/json-configs", require("./routes/jsonConfigs.routes"));
|
|
838
|
+
router.use("/api/markdowns", require("./routes/markdowns.routes"));
|
|
765
839
|
router.use("/api/assets", require("./routes/assets.routes"));
|
|
766
840
|
router.use("/api/i18n", require("./routes/i18n.routes"));
|
|
767
841
|
router.use("/api/headless", require("./routes/headless.routes"));
|
|
@@ -1365,6 +1439,39 @@ function createMiddleware(options = {}) {
|
|
|
1365
1439
|
});
|
|
1366
1440
|
});
|
|
1367
1441
|
|
|
1442
|
+
// Admin markdowns page (protected by basic auth)
|
|
1443
|
+
router.get(`${adminPath}/markdowns`, basicAuth, (req, res) => {
|
|
1444
|
+
const templatePath = path.join(
|
|
1445
|
+
__dirname,
|
|
1446
|
+
"..",
|
|
1447
|
+
"views",
|
|
1448
|
+
"admin-markdowns.ejs",
|
|
1449
|
+
);
|
|
1450
|
+
fs.readFile(templatePath, "utf8", (err, template) => {
|
|
1451
|
+
if (err) {
|
|
1452
|
+
console.error("Error reading template:", err);
|
|
1453
|
+
return res.status(500).send("Error loading page");
|
|
1454
|
+
}
|
|
1455
|
+
try {
|
|
1456
|
+
const html = ejs.render(
|
|
1457
|
+
template,
|
|
1458
|
+
{
|
|
1459
|
+
baseUrl: req.baseUrl,
|
|
1460
|
+
adminPath,
|
|
1461
|
+
endpointRegistry,
|
|
1462
|
+
},
|
|
1463
|
+
{
|
|
1464
|
+
filename: templatePath,
|
|
1465
|
+
},
|
|
1466
|
+
);
|
|
1467
|
+
res.send(html);
|
|
1468
|
+
} catch (renderErr) {
|
|
1469
|
+
console.error("Error rendering template:", renderErr);
|
|
1470
|
+
res.status(500).send("Error rendering page");
|
|
1471
|
+
}
|
|
1472
|
+
});
|
|
1473
|
+
});
|
|
1474
|
+
|
|
1368
1475
|
// Admin assets page (protected by basic auth)
|
|
1369
1476
|
router.get(`${adminPath}/assets`, basicAuth, (req, res) => {
|
|
1370
1477
|
const templatePath = path.join(
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
const mongoose = require('mongoose');
|
|
2
|
+
|
|
3
|
+
const agentSchema = new mongoose.Schema({
|
|
4
|
+
name: {
|
|
5
|
+
type: String,
|
|
6
|
+
required: true,
|
|
7
|
+
trim: true
|
|
8
|
+
},
|
|
9
|
+
systemPrompt: {
|
|
10
|
+
type: String,
|
|
11
|
+
default: `You are a helpful assistant with access to specific tools for querying data.
|
|
12
|
+
|
|
13
|
+
AVAILABLE TOOLS:
|
|
14
|
+
|
|
15
|
+
1. query_database: Query the MongoDB database for insights.
|
|
16
|
+
- Parameters:
|
|
17
|
+
- modelName (required): The name of the Mongoose model (e.g., User, Markdown, AuditEvent)
|
|
18
|
+
- query (required): The MongoDB query object
|
|
19
|
+
- limit (optional): Limit the number of results (default: 5)
|
|
20
|
+
- Usage: Use this when you need to fetch specific data from the database.
|
|
21
|
+
|
|
22
|
+
2. get_system_stats: Get general statistics about the system.
|
|
23
|
+
- Parameters: None
|
|
24
|
+
- Usage: Use this when you need overall counts of users, markdowns, and other system entities.
|
|
25
|
+
|
|
26
|
+
3. raw_db_query: Execute raw MongoDB queries for database exploration.
|
|
27
|
+
- Parameters:
|
|
28
|
+
- queryType (required): The type of raw query to execute
|
|
29
|
+
• listDatabases: List all databases (requires admin access)
|
|
30
|
+
• listCollections: List all collections in a database
|
|
31
|
+
• countDocuments: Count documents in a collection
|
|
32
|
+
• findOne: Find a single document in a collection
|
|
33
|
+
• aggregate: Run aggregation pipeline
|
|
34
|
+
• adminCommand: Execute admin commands
|
|
35
|
+
- database (optional): Database name (defaults to current database)
|
|
36
|
+
- collection (required for collection queries): Collection name
|
|
37
|
+
- filter (optional): MongoDB filter/query object. Can be:
|
|
38
|
+
• A JSON object: { createdAt: { $gte: new Date() } }
|
|
39
|
+
• A JSON string: '{"createdAt": {"$gte": {"$date": "2024-01-01"}}}'
|
|
40
|
+
• For aggregate: an array of pipeline stages as object or JSON string
|
|
41
|
+
- limit (optional): Limit results (default: 10)
|
|
42
|
+
- adminCommand (optional): Admin command for adminCommand queryType (as object or JSON string)
|
|
43
|
+
- Usage: Use this to discover collection names, databases, or run admin commands.
|
|
44
|
+
- IMPORTANT: For complex queries, use JSON string format to avoid parsing issues
|
|
45
|
+
|
|
46
|
+
IMPORTANT ERROR HANDLING INSTRUCTIONS:
|
|
47
|
+
- When a tool returns an error, it will be in structured JSON format with error details
|
|
48
|
+
- ALWAYS provide a friendly, conversational response to the user about tool errors
|
|
49
|
+
- NEVER show raw error JSON to users
|
|
50
|
+
- DO: "I had trouble accessing the database. Let me try a different approach..."
|
|
51
|
+
- DO NOT: Show the actual error JSON to users
|
|
52
|
+
- Extract the error message and provide helpful suggestions based on the error context
|
|
53
|
+
- If an error is not recoverable, explain why and suggest alternatives
|
|
54
|
+
- If an error is recoverable, explain what you'll try next
|
|
55
|
+
- Use the error suggestions provided in the tool response to inform your response
|
|
56
|
+
|
|
57
|
+
INSTRUCTIONS:
|
|
58
|
+
- Always use tools when you need actual data from the database
|
|
59
|
+
- Never make up data or statistics
|
|
60
|
+
- For database queries, use exact model names as they appear in the system
|
|
61
|
+
- When using query_database, construct appropriate MongoDB query objects based on the user's request
|
|
62
|
+
- If you don't have enough information for a query, ask clarifying questions
|
|
63
|
+
- Use get_system_stats for high-level overview requests
|
|
64
|
+
- Use raw_db_query for:
|
|
65
|
+
* Discovering what collections exist: queryType: "listCollections"
|
|
66
|
+
* Finding database names: queryType: "listDatabases" (may require admin)
|
|
67
|
+
* Counting documents: queryType: "countDocuments" with collection and filter
|
|
68
|
+
* Exploring collection structure: queryType: "findOne" or "aggregate"
|
|
69
|
+
- For specific records, use query_database with appropriate filters
|
|
70
|
+
|
|
71
|
+
Respond helpfully and only use the tools when necessary for accurate information. Always provide friendly error messages to users when tools fail.`
|
|
72
|
+
},
|
|
73
|
+
providerKey: {
|
|
74
|
+
type: String,
|
|
75
|
+
required: true
|
|
76
|
+
},
|
|
77
|
+
model: {
|
|
78
|
+
type: String,
|
|
79
|
+
required: true
|
|
80
|
+
},
|
|
81
|
+
tools: {
|
|
82
|
+
type: [String],
|
|
83
|
+
default: []
|
|
84
|
+
},
|
|
85
|
+
temperature: {
|
|
86
|
+
type: Number,
|
|
87
|
+
default: 0.7
|
|
88
|
+
},
|
|
89
|
+
maxIterations: {
|
|
90
|
+
type: Number,
|
|
91
|
+
default: 10
|
|
92
|
+
},
|
|
93
|
+
orgId: {
|
|
94
|
+
type: mongoose.Schema.Types.ObjectId,
|
|
95
|
+
ref: 'Organization'
|
|
96
|
+
},
|
|
97
|
+
ownerUserId: {
|
|
98
|
+
type: mongoose.Schema.Types.ObjectId,
|
|
99
|
+
ref: 'User'
|
|
100
|
+
}
|
|
101
|
+
}, {
|
|
102
|
+
timestamps: true
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
module.exports = mongoose.model('Agent', agentSchema);
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
const mongoose = require('mongoose');
|
|
2
|
+
const { ObjectId } = mongoose.Schema.Types;
|
|
3
|
+
|
|
4
|
+
const agentMessageSchema = new mongoose.Schema({
|
|
5
|
+
agentId: {
|
|
6
|
+
type: ObjectId,
|
|
7
|
+
ref: 'Agent',
|
|
8
|
+
required: true,
|
|
9
|
+
index: true
|
|
10
|
+
},
|
|
11
|
+
chatId: {
|
|
12
|
+
type: String,
|
|
13
|
+
required: true,
|
|
14
|
+
index: true
|
|
15
|
+
},
|
|
16
|
+
role: {
|
|
17
|
+
type: String,
|
|
18
|
+
enum: ['user', 'assistant', 'system', 'tool'],
|
|
19
|
+
required: true
|
|
20
|
+
},
|
|
21
|
+
content: {
|
|
22
|
+
type: String,
|
|
23
|
+
required: function() {
|
|
24
|
+
// Content is not required if:
|
|
25
|
+
// 1. Role is 'tool' (content might be in metadata or implied) - though usually tool has content
|
|
26
|
+
// 2. Role is 'assistant' AND it has toolCalls (OpenAI often returns null content with tool calls)
|
|
27
|
+
if (this.role === 'tool') return false;
|
|
28
|
+
if (this.role === 'assistant' && this.toolCalls && this.toolCalls.length > 0) return false;
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
toolCalls: [{
|
|
33
|
+
name: String,
|
|
34
|
+
arguments: mongoose.Schema.Types.Mixed,
|
|
35
|
+
toolCallId: String
|
|
36
|
+
}],
|
|
37
|
+
toolCallId: {
|
|
38
|
+
type: String,
|
|
39
|
+
index: true
|
|
40
|
+
},
|
|
41
|
+
metadata: {
|
|
42
|
+
tokens: Number,
|
|
43
|
+
processingTime: Number,
|
|
44
|
+
model: String,
|
|
45
|
+
provider: String,
|
|
46
|
+
timestamp: Date,
|
|
47
|
+
temperature: Number
|
|
48
|
+
},
|
|
49
|
+
createdAt: {
|
|
50
|
+
type: Date,
|
|
51
|
+
default: Date.now,
|
|
52
|
+
index: true
|
|
53
|
+
},
|
|
54
|
+
updatedAt: {
|
|
55
|
+
type: Date,
|
|
56
|
+
default: Date.now
|
|
57
|
+
}
|
|
58
|
+
}, {
|
|
59
|
+
timestamps: true,
|
|
60
|
+
toJSON: { virtuals: true },
|
|
61
|
+
toObject: { virtuals: true }
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
// Compound index for efficient session history retrieval
|
|
65
|
+
agentMessageSchema.index(
|
|
66
|
+
{ agentId: 1, chatId: 1, createdAt: 1 },
|
|
67
|
+
{ name: 'session_history_idx' }
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
// Index for tool call lookup
|
|
71
|
+
agentMessageSchema.index(
|
|
72
|
+
{ toolCallId: 1 },
|
|
73
|
+
{ name: 'tool_call_idx' }
|
|
74
|
+
);
|
|
75
|
+
|
|
76
|
+
// Index for searching content
|
|
77
|
+
agentMessageSchema.index(
|
|
78
|
+
{ content: 'text' },
|
|
79
|
+
{ name: 'content_search_idx' }
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
module.exports = mongoose.model('AgentMessage', agentMessageSchema);
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
const mongoose = require('mongoose');
|
|
2
|
+
|
|
3
|
+
const markdownSchema = new mongoose.Schema(
|
|
4
|
+
{
|
|
5
|
+
title: {
|
|
6
|
+
type: String,
|
|
7
|
+
required: true,
|
|
8
|
+
trim: true,
|
|
9
|
+
},
|
|
10
|
+
slug: {
|
|
11
|
+
type: String,
|
|
12
|
+
required: true,
|
|
13
|
+
index: true,
|
|
14
|
+
trim: true,
|
|
15
|
+
},
|
|
16
|
+
category: {
|
|
17
|
+
type: String,
|
|
18
|
+
required: true,
|
|
19
|
+
index: true,
|
|
20
|
+
trim: true,
|
|
21
|
+
default: 'general',
|
|
22
|
+
},
|
|
23
|
+
group_code: {
|
|
24
|
+
type: String,
|
|
25
|
+
required: false,
|
|
26
|
+
index: true,
|
|
27
|
+
trim: true,
|
|
28
|
+
default: '',
|
|
29
|
+
},
|
|
30
|
+
markdownRaw: {
|
|
31
|
+
type: String,
|
|
32
|
+
required: true,
|
|
33
|
+
default: '',
|
|
34
|
+
},
|
|
35
|
+
publicEnabled: {
|
|
36
|
+
type: Boolean,
|
|
37
|
+
default: false,
|
|
38
|
+
index: true,
|
|
39
|
+
},
|
|
40
|
+
cacheTtlSeconds: {
|
|
41
|
+
type: Number,
|
|
42
|
+
default: 0,
|
|
43
|
+
},
|
|
44
|
+
status: {
|
|
45
|
+
type: String,
|
|
46
|
+
enum: ['draft', 'published', 'archived'],
|
|
47
|
+
default: 'draft',
|
|
48
|
+
index: true,
|
|
49
|
+
},
|
|
50
|
+
ownerUserId: {
|
|
51
|
+
type: mongoose.Schema.Types.ObjectId,
|
|
52
|
+
ref: 'User',
|
|
53
|
+
index: true,
|
|
54
|
+
default: null,
|
|
55
|
+
},
|
|
56
|
+
orgId: {
|
|
57
|
+
type: mongoose.Schema.Types.ObjectId,
|
|
58
|
+
ref: 'Organization',
|
|
59
|
+
index: true,
|
|
60
|
+
default: null,
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
{ timestamps: true },
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
// Compound unique index for fast lookups
|
|
67
|
+
markdownSchema.index({ category: 1, group_code: 1, slug: 1 }, { unique: true });
|
|
68
|
+
|
|
69
|
+
// Additional indexes for common queries
|
|
70
|
+
markdownSchema.index({ status: 1, publicEnabled: 1 });
|
|
71
|
+
markdownSchema.index({ category: 1, status: 1 });
|
|
72
|
+
markdownSchema.index({ ownerUserId: 1, createdAt: -1 });
|
|
73
|
+
markdownSchema.index({ orgId: 1, createdAt: -1 });
|
|
74
|
+
|
|
75
|
+
module.exports = mongoose.model('Markdown', markdownSchema);
|
package/src/models/ScriptRun.js
CHANGED
|
@@ -14,6 +14,14 @@ const scriptRunSchema = new mongoose.Schema(
|
|
|
14
14
|
finishedAt: { type: Date, default: null },
|
|
15
15
|
exitCode: { type: Number, default: null },
|
|
16
16
|
outputTail: { type: String, default: '' },
|
|
17
|
+
fullOutput: { type: String, default: '' },
|
|
18
|
+
programmaticOutput: { type: String, default: '' },
|
|
19
|
+
returnResult: { type: String, default: '' },
|
|
20
|
+
lastConsoleLog: { type: String, default: '' },
|
|
21
|
+
outputType: { type: String, enum: ['return', 'console', 'none'], default: 'none' },
|
|
22
|
+
outputSize: { type: Number, default: 0 },
|
|
23
|
+
lineCount: { type: Number, default: 0 },
|
|
24
|
+
lastOutputUpdate: { type: Date, default: null },
|
|
17
25
|
meta: { type: mongoose.Schema.Types.Mixed, default: null },
|
|
18
26
|
},
|
|
19
27
|
{ timestamps: true, collection: 'script_runs' },
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
const mongoose = require('mongoose');
|
|
2
|
+
|
|
3
|
+
const telegramBotSchema = new mongoose.Schema({
|
|
4
|
+
name: {
|
|
5
|
+
type: String,
|
|
6
|
+
required: true,
|
|
7
|
+
trim: true
|
|
8
|
+
},
|
|
9
|
+
token: {
|
|
10
|
+
type: String,
|
|
11
|
+
required: true,
|
|
12
|
+
trim: true
|
|
13
|
+
},
|
|
14
|
+
isActive: {
|
|
15
|
+
type: Boolean,
|
|
16
|
+
default: false
|
|
17
|
+
},
|
|
18
|
+
allowedUserIds: {
|
|
19
|
+
type: [String],
|
|
20
|
+
default: []
|
|
21
|
+
},
|
|
22
|
+
defaultAgentId: {
|
|
23
|
+
type: mongoose.Schema.Types.ObjectId,
|
|
24
|
+
ref: 'Agent'
|
|
25
|
+
},
|
|
26
|
+
orgId: {
|
|
27
|
+
type: mongoose.Schema.Types.ObjectId,
|
|
28
|
+
ref: 'Organization'
|
|
29
|
+
},
|
|
30
|
+
status: {
|
|
31
|
+
type: String,
|
|
32
|
+
enum: ['stopped', 'running', 'error'],
|
|
33
|
+
default: 'stopped'
|
|
34
|
+
},
|
|
35
|
+
lastError: {
|
|
36
|
+
type: String
|
|
37
|
+
}
|
|
38
|
+
}, {
|
|
39
|
+
timestamps: true
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
module.exports = mongoose.model('TelegramBot', telegramBotSchema);
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
const express = require('express');
|
|
2
|
+
const router = express.Router();
|
|
3
|
+
const adminAgentsController = require('../controllers/adminAgents.controller');
|
|
4
|
+
const { basicAuth } = require('../middleware/auth');
|
|
5
|
+
|
|
6
|
+
router.use(basicAuth);
|
|
7
|
+
|
|
8
|
+
router.get('/', adminAgentsController.listAgents);
|
|
9
|
+
router.post('/', adminAgentsController.createAgent);
|
|
10
|
+
router.put('/:id', adminAgentsController.updateAgent);
|
|
11
|
+
router.delete('/:id', adminAgentsController.deleteAgent);
|
|
12
|
+
|
|
13
|
+
module.exports = router;
|
|
@@ -5,6 +5,7 @@ const adminLlmController = require("../controllers/adminLlm.controller");
|
|
|
5
5
|
const rateLimiter = require("../services/rateLimiter.service");
|
|
6
6
|
|
|
7
7
|
router.get("/config", basicAuth, adminLlmController.getConfig);
|
|
8
|
+
router.get("/providers", basicAuth, adminLlmController.listProviders);
|
|
8
9
|
router.post("/config", basicAuth, rateLimiter.limit("llmConfigLimiter"), adminLlmController.saveConfig);
|
|
9
10
|
router.get("/openrouter/models", basicAuth, adminLlmController.listOpenRouterModels);
|
|
10
11
|
router.post("/prompts/:key/test", basicAuth, rateLimiter.limit("llmConfigLimiter"), adminLlmController.testPrompt);
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
const express = require('express');
|
|
2
|
+
const router = express.Router();
|
|
3
|
+
const { basicAuth } = require('../middleware/auth');
|
|
4
|
+
|
|
5
|
+
const adminMarkdownsController = require('../controllers/adminMarkdowns.controller');
|
|
6
|
+
|
|
7
|
+
router.get('/', basicAuth, adminMarkdownsController.list);
|
|
8
|
+
router.get('/group-codes/:category', basicAuth, adminMarkdownsController.getGroupCodes);
|
|
9
|
+
router.get('/folder/:category/:group_code?', basicAuth, adminMarkdownsController.getFolderContents);
|
|
10
|
+
router.get('/:id', basicAuth, adminMarkdownsController.get);
|
|
11
|
+
router.post('/', basicAuth, adminMarkdownsController.create);
|
|
12
|
+
router.put('/:id', basicAuth, adminMarkdownsController.update);
|
|
13
|
+
router.delete('/:id', basicAuth, adminMarkdownsController.remove);
|
|
14
|
+
router.post('/validate-path', basicAuth, adminMarkdownsController.validatePath);
|
|
15
|
+
|
|
16
|
+
module.exports = router;
|
|
@@ -10,7 +10,10 @@ router.get('/', controller.listScripts);
|
|
|
10
10
|
router.post('/', controller.createScript);
|
|
11
11
|
router.get('/runs', controller.listRuns);
|
|
12
12
|
router.get('/runs/:runId', controller.getRun);
|
|
13
|
-
router.get('/runs/:runId/stream', controller.
|
|
13
|
+
router.get('/runs/:runId/stream', controller.streamRunLogs);
|
|
14
|
+
router.get('/runs/:runId/programmatic-output', controller.getProgrammaticOutput);
|
|
15
|
+
router.get('/runs/:runId/full-output', controller.getFullOutput);
|
|
16
|
+
router.get('/runs/:runId/download', controller.downloadOutput);
|
|
14
17
|
|
|
15
18
|
router.get('/:id', controller.getScript);
|
|
16
19
|
router.put('/:id', controller.updateScript);
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
const express = require('express');
|
|
2
|
+
const router = express.Router();
|
|
3
|
+
const adminTelegramController = require('../controllers/adminTelegram.controller');
|
|
4
|
+
const { basicAuth } = require('../middleware/auth');
|
|
5
|
+
|
|
6
|
+
router.use(basicAuth);
|
|
7
|
+
|
|
8
|
+
router.get('/', adminTelegramController.listBots);
|
|
9
|
+
router.post('/', adminTelegramController.createBot);
|
|
10
|
+
router.put('/:id', adminTelegramController.updateBot);
|
|
11
|
+
router.delete('/:id', adminTelegramController.deleteBot);
|
|
12
|
+
router.post('/:id/toggle', adminTelegramController.toggleBot);
|
|
13
|
+
|
|
14
|
+
module.exports = router;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
const express = require('express');
|
|
2
|
+
const router = express.Router();
|
|
3
|
+
|
|
4
|
+
const markdownsController = require('../controllers/markdowns.controller');
|
|
5
|
+
|
|
6
|
+
// JSON versions (more specific first)
|
|
7
|
+
router.get('/:category/:group_code/:slug/json', markdownsController.getByPath);
|
|
8
|
+
router.get('/:category/:slug/json', markdownsController.getByPath);
|
|
9
|
+
|
|
10
|
+
// Raw versions
|
|
11
|
+
router.get('/:category/:group_code/:slug', markdownsController.getByPath);
|
|
12
|
+
router.get('/:category/:slug', markdownsController.getByPath); // No group_code
|
|
13
|
+
|
|
14
|
+
router.get('/search', markdownsController.search);
|
|
15
|
+
|
|
16
|
+
module.exports = router;
|