dank-ai 1.0.31 → 1.0.33
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/README.md +49 -50
- package/bin/dank +1 -0
- package/docker/entrypoint.js +140 -353
- package/lib/agent.js +100 -25
- package/lib/cli/init.js +1 -14
- package/lib/cli/production-build.js +6 -8
- package/lib/config.js +32 -33
- package/lib/constants.js +23 -6
- package/lib/docker/manager.js +161 -42
- package/lib/project.js +1 -4
- package/package.json +1 -1
package/docker/entrypoint.js
CHANGED
|
@@ -56,11 +56,17 @@ class AgentRuntime {
|
|
|
56
56
|
this.httpEnabled = process.env.HTTP_ENABLED === "true";
|
|
57
57
|
this.httpPort = parseInt(process.env.HTTP_PORT) || 3000;
|
|
58
58
|
this.httpHost = process.env.HTTP_HOST || "0.0.0.0";
|
|
59
|
+
|
|
60
|
+
// Main agent port (used for health, prompting, and optionally HTTP API)
|
|
61
|
+
this.mainPort = parseInt(process.env.DOCKER_PORT) || 3000;
|
|
62
|
+
logger.info(`🔌 Main agent port configured: ${this.mainPort} (from DOCKER_PORT: ${process.env.DOCKER_PORT || 'default'})`);
|
|
59
63
|
|
|
60
|
-
//
|
|
61
|
-
this.
|
|
62
|
-
this.
|
|
64
|
+
// Single Express app for health, prompting, and HTTP API
|
|
65
|
+
this.mainApp = express();
|
|
66
|
+
this.mainApp.use(express.json({ limit: "10mb" }));
|
|
67
|
+
this.mainApp.use(express.urlencoded({ extended: true, limit: "10mb" }));
|
|
63
68
|
|
|
69
|
+
// Setup health endpoints on main app
|
|
64
70
|
this.setupHealthEndpoints();
|
|
65
71
|
}
|
|
66
72
|
|
|
@@ -80,18 +86,25 @@ class AgentRuntime {
|
|
|
80
86
|
// Setup agent handlers
|
|
81
87
|
await this.setupHandlers();
|
|
82
88
|
|
|
83
|
-
//
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
// Start HTTP server if enabled
|
|
89
|
+
// Setup HTTP middleware (CORS, rate limiting) if HTTP is enabled
|
|
90
|
+
// This must be done BEFORE routes are added
|
|
87
91
|
if (this.httpEnabled) {
|
|
88
|
-
await this.
|
|
89
|
-
this.startHttpServer();
|
|
92
|
+
await this.setupHttpMiddleware();
|
|
90
93
|
}
|
|
91
94
|
|
|
92
|
-
// Setup
|
|
95
|
+
// Setup user routes on main app (if any routes exist in agent code)
|
|
96
|
+
// Routes are always added to the main app (same server as health and prompting)
|
|
97
|
+
await this.setupAgentRoutes();
|
|
98
|
+
|
|
99
|
+
// Setup direct prompting server (adds /prompt endpoint to main app)
|
|
93
100
|
await this.setupDirectPromptingServer();
|
|
94
101
|
|
|
102
|
+
// Set up 404 and error handlers AFTER all routes (including /prompt) are registered
|
|
103
|
+
this.setupDefaultRoutes();
|
|
104
|
+
|
|
105
|
+
// Start the main server (handles health, prompting, and user routes)
|
|
106
|
+
this.startMainServer();
|
|
107
|
+
|
|
95
108
|
// Mark as running
|
|
96
109
|
this.isRunning = true;
|
|
97
110
|
|
|
@@ -418,10 +431,10 @@ class AgentRuntime {
|
|
|
418
431
|
}
|
|
419
432
|
|
|
420
433
|
/**
|
|
421
|
-
* Setup health check endpoints
|
|
434
|
+
* Setup health check endpoints on main app
|
|
422
435
|
*/
|
|
423
436
|
setupHealthEndpoints() {
|
|
424
|
-
this.
|
|
437
|
+
this.mainApp.get("/health", (req, res) => {
|
|
425
438
|
res.json({
|
|
426
439
|
status: this.isRunning ? "healthy" : "starting",
|
|
427
440
|
agent: {
|
|
@@ -439,7 +452,7 @@ class AgentRuntime {
|
|
|
439
452
|
});
|
|
440
453
|
});
|
|
441
454
|
|
|
442
|
-
this.
|
|
455
|
+
this.mainApp.get("/status", (req, res) => {
|
|
443
456
|
res.json({
|
|
444
457
|
agent: {
|
|
445
458
|
name: this.agentName,
|
|
@@ -456,7 +469,7 @@ class AgentRuntime {
|
|
|
456
469
|
http: {
|
|
457
470
|
enabled: this.httpEnabled,
|
|
458
471
|
port: this.httpEnabled ? this.httpPort : null,
|
|
459
|
-
routes: this.httpEnabled && this.
|
|
472
|
+
routes: this.httpEnabled && this.mainApp ? this.getRoutesList() : [],
|
|
460
473
|
},
|
|
461
474
|
handlers: Array.from(this.handlers.keys()),
|
|
462
475
|
environment: {
|
|
@@ -469,22 +482,15 @@ class AgentRuntime {
|
|
|
469
482
|
}
|
|
470
483
|
|
|
471
484
|
/**
|
|
472
|
-
* Setup HTTP
|
|
485
|
+
* Setup HTTP middleware (CORS, rate limiting) on main app
|
|
486
|
+
* This is only called if HTTP is explicitly enabled via configuration
|
|
473
487
|
*/
|
|
474
|
-
async
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
logger.info(`Setting up HTTP server on port ${this.httpPort}`);
|
|
478
|
-
|
|
479
|
-
this.httpApp = express();
|
|
480
|
-
|
|
481
|
-
// Basic middleware
|
|
482
|
-
this.httpApp.use(express.json({ limit: "10mb" }));
|
|
483
|
-
this.httpApp.use(express.urlencoded({ extended: true, limit: "10mb" }));
|
|
488
|
+
async setupHttpMiddleware() {
|
|
489
|
+
logger.info(`Setting up HTTP middleware on main server`);
|
|
484
490
|
|
|
485
491
|
// CORS if enabled
|
|
486
492
|
if (process.env.HTTP_CORS !== "false") {
|
|
487
|
-
this.
|
|
493
|
+
this.mainApp.use((req, res, next) => {
|
|
488
494
|
res.header("Access-Control-Allow-Origin", "*");
|
|
489
495
|
res.header(
|
|
490
496
|
"Access-Control-Allow-Methods",
|
|
@@ -512,50 +518,31 @@ class AgentRuntime {
|
|
|
512
518
|
max: parseInt(process.env.HTTP_RATE_LIMIT_MAX) || 100,
|
|
513
519
|
message: process.env.HTTP_RATE_LIMIT_MESSAGE || "Too many requests",
|
|
514
520
|
});
|
|
515
|
-
this.
|
|
521
|
+
this.mainApp.use(limiter);
|
|
516
522
|
}
|
|
517
|
-
|
|
518
|
-
// Setup routes from agent configuration
|
|
519
|
-
await this.setupAgentRoutes();
|
|
520
|
-
|
|
521
|
-
// Default routes
|
|
522
|
-
this.httpApp.get("/", (req, res) => {
|
|
523
|
-
res.json({
|
|
524
|
-
message: `🤖 ${this.agentName} HTTP Server`,
|
|
525
|
-
agent: this.agentName,
|
|
526
|
-
version: "1.0.0",
|
|
527
|
-
endpoints: this.getRoutesList(),
|
|
528
|
-
timestamp: new Date().toISOString(),
|
|
529
|
-
});
|
|
530
|
-
});
|
|
531
|
-
|
|
532
|
-
// 404 handler
|
|
533
|
-
this.httpApp.use((req, res) => {
|
|
534
|
-
res.status(404).json({
|
|
535
|
-
error: "Not Found",
|
|
536
|
-
message: `Cannot ${req.method} ${req.path}`,
|
|
537
|
-
availableRoutes: this.getRoutesList(),
|
|
538
|
-
});
|
|
539
|
-
});
|
|
540
|
-
|
|
541
|
-
// Error handler
|
|
542
|
-
this.httpApp.use((err, req, res, next) => {
|
|
543
|
-
logger.error("HTTP server error:", err);
|
|
544
|
-
res.status(500).json({
|
|
545
|
-
error: "Internal Server Error",
|
|
546
|
-
message:
|
|
547
|
-
process.env.NODE_ENV === "development"
|
|
548
|
-
? err.message
|
|
549
|
-
: "Something went wrong",
|
|
550
|
-
});
|
|
551
|
-
});
|
|
552
523
|
}
|
|
553
524
|
|
|
554
525
|
/**
|
|
555
526
|
* Setup routes defined in agent configuration
|
|
527
|
+
* Routes are always added to the main app (same server as health and prompting)
|
|
528
|
+
* NOTE: Does NOT set up 404 handler - that must be done AFTER all routes including /prompt
|
|
556
529
|
*/
|
|
557
530
|
async setupAgentRoutes() {
|
|
558
|
-
if (!this.agentCode || !this.agentCode.routes)
|
|
531
|
+
if (!this.agentCode || !this.agentCode.routes) {
|
|
532
|
+
// Set up default root route only (404 handler will be set up later)
|
|
533
|
+
this.mainApp.get("/", (req, res) => {
|
|
534
|
+
res.json({
|
|
535
|
+
message: `🤖 ${this.agentName} HTTP Server`,
|
|
536
|
+
agent: this.agentName,
|
|
537
|
+
version: "1.0.0",
|
|
538
|
+
endpoints: this.getRoutesList(),
|
|
539
|
+
timestamp: new Date().toISOString(),
|
|
540
|
+
});
|
|
541
|
+
});
|
|
542
|
+
return;
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
logger.info(`Setting up user routes on main server`);
|
|
559
546
|
|
|
560
547
|
// Setup routes from agent code
|
|
561
548
|
Object.entries(this.agentCode.routes).forEach(([path, handlers]) => {
|
|
@@ -563,14 +550,9 @@ class AgentRuntime {
|
|
|
563
550
|
Object.entries(handlers).forEach(([method, handler]) => {
|
|
564
551
|
if (typeof handler === "function") {
|
|
565
552
|
const lowerMethod = method.toLowerCase();
|
|
566
|
-
if (this.
|
|
567
|
-
//
|
|
568
|
-
|
|
569
|
-
method,
|
|
570
|
-
path,
|
|
571
|
-
handler
|
|
572
|
-
);
|
|
573
|
-
this.httpApp[lowerMethod](path, wrappedHandler);
|
|
553
|
+
if (this.mainApp[lowerMethod]) {
|
|
554
|
+
// Register route handler directly on main app
|
|
555
|
+
this.mainApp[lowerMethod](path, handler);
|
|
574
556
|
logger.info(`Registered route: ${method.toUpperCase()} ${path}`);
|
|
575
557
|
}
|
|
576
558
|
}
|
|
@@ -582,21 +564,59 @@ class AgentRuntime {
|
|
|
582
564
|
if (this.agentCode.middleware && Array.isArray(this.agentCode.middleware)) {
|
|
583
565
|
this.agentCode.middleware.forEach((middleware) => {
|
|
584
566
|
if (typeof middleware === "function") {
|
|
585
|
-
this.
|
|
567
|
+
this.mainApp.use(middleware);
|
|
586
568
|
logger.info("Registered custom middleware");
|
|
587
569
|
}
|
|
588
570
|
});
|
|
589
571
|
}
|
|
572
|
+
|
|
573
|
+
// Set up default root route (404 handler will be set up later, after /prompt)
|
|
574
|
+
this.mainApp.get("/", (req, res) => {
|
|
575
|
+
res.json({
|
|
576
|
+
message: `🤖 ${this.agentName} HTTP Server`,
|
|
577
|
+
agent: this.agentName,
|
|
578
|
+
version: "1.0.0",
|
|
579
|
+
endpoints: this.getRoutesList(),
|
|
580
|
+
timestamp: new Date().toISOString(),
|
|
581
|
+
});
|
|
582
|
+
});
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
/**
|
|
586
|
+
* Setup 404 and error handlers on main app
|
|
587
|
+
* MUST be called AFTER all routes (including /prompt) are registered
|
|
588
|
+
*/
|
|
589
|
+
setupDefaultRoutes() {
|
|
590
|
+
// 404 handler (must be after ALL routes, including /prompt)
|
|
591
|
+
this.mainApp.use((req, res) => {
|
|
592
|
+
res.status(404).json({
|
|
593
|
+
error: "Not Found",
|
|
594
|
+
message: `Cannot ${req.method} ${req.path}`,
|
|
595
|
+
availableRoutes: this.getRoutesList(),
|
|
596
|
+
});
|
|
597
|
+
});
|
|
598
|
+
|
|
599
|
+
// Error handler (must be last)
|
|
600
|
+
this.mainApp.use((err, req, res, next) => {
|
|
601
|
+
logger.error("HTTP server error:", err);
|
|
602
|
+
res.status(500).json({
|
|
603
|
+
error: "Internal Server Error",
|
|
604
|
+
message:
|
|
605
|
+
process.env.NODE_ENV === "development"
|
|
606
|
+
? err.message
|
|
607
|
+
: "Something went wrong",
|
|
608
|
+
});
|
|
609
|
+
});
|
|
590
610
|
}
|
|
591
611
|
|
|
592
612
|
/**
|
|
593
613
|
* Get list of registered routes
|
|
594
614
|
*/
|
|
595
615
|
getRoutesList() {
|
|
596
|
-
if (!this.
|
|
616
|
+
if (!this.mainApp) return [];
|
|
597
617
|
|
|
598
618
|
const routes = [];
|
|
599
|
-
this.
|
|
619
|
+
this.mainApp._router.stack.forEach((middleware) => {
|
|
600
620
|
if (middleware.route) {
|
|
601
621
|
const methods = Object.keys(middleware.route.methods);
|
|
602
622
|
routes.push({
|
|
@@ -610,167 +630,66 @@ class AgentRuntime {
|
|
|
610
630
|
}
|
|
611
631
|
|
|
612
632
|
/**
|
|
613
|
-
* Start health
|
|
633
|
+
* Start main server (handles health, prompting, and optionally HTTP API)
|
|
634
|
+
* The main server ALWAYS runs on the port specified by setPromptingServer (or default 3000)
|
|
614
635
|
*/
|
|
615
|
-
|
|
616
|
-
const port =
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
);
|
|
636
|
+
startMainServer() {
|
|
637
|
+
const port = this.mainPort;
|
|
638
|
+
const host = "0.0.0.0";
|
|
639
|
+
|
|
640
|
+
this.mainApp.listen(port, host, () => {
|
|
641
|
+
logger.info(`🌐 Main HTTP server listening on ${host}:${port}`);
|
|
642
|
+
logger.info(`🔗 Health check: GET http://localhost:${port}/health`);
|
|
643
|
+
logger.info(`🔗 Status: GET http://localhost:${port}/status`);
|
|
644
|
+
|
|
645
|
+
const directPromptingEnabled =
|
|
646
|
+
process.env.DIRECT_PROMPTING_ENABLED !== "false";
|
|
647
|
+
if (directPromptingEnabled) {
|
|
648
|
+
logger.info(`📡 Direct prompting: POST http://localhost:${port}/prompt`);
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
if (this.httpEnabled) {
|
|
652
|
+
logger.info(`🔗 HTTP API routes: http://localhost:${port}`);
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
logger.info(`✅ Main server ready on port ${port}`);
|
|
636
656
|
});
|
|
637
657
|
}
|
|
638
658
|
|
|
639
659
|
/**
|
|
640
|
-
* Setup direct prompting server (
|
|
660
|
+
* Setup direct prompting server (HTTP only)
|
|
661
|
+
* Always sets up /prompt endpoint - the main HTTP server always runs
|
|
641
662
|
*/
|
|
642
663
|
async setupDirectPromptingServer() {
|
|
643
|
-
const directPromptingEnabled =
|
|
644
|
-
process.env.DIRECT_PROMPTING_ENABLED !== "false";
|
|
645
|
-
logger.info(`🔍 Direct prompting enabled: ${directPromptingEnabled}`);
|
|
646
|
-
if (!directPromptingEnabled) return;
|
|
647
|
-
|
|
648
|
-
const protocol = process.env.DIRECT_PROMPTING_PROTOCOL || "websocket";
|
|
649
664
|
const port = parseInt(process.env.DOCKER_PORT) || 3000;
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
);
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
665
|
+
const directPromptingEnabled = process.env.DIRECT_PROMPTING_ENABLED !== "false";
|
|
666
|
+
|
|
667
|
+
logger.info(`🔍 Checking direct prompting setup:`);
|
|
668
|
+
logger.info(` - DOCKER_PORT: ${process.env.DOCKER_PORT || 'not set (defaulting to 3000)'}`);
|
|
669
|
+
logger.info(` - DIRECT_PROMPTING_ENABLED: ${process.env.DIRECT_PROMPTING_ENABLED || 'not set'}`);
|
|
670
|
+
logger.info(` - Direct prompting enabled: ${directPromptingEnabled}`);
|
|
671
|
+
|
|
672
|
+
// Always set up the /prompt endpoint if DIRECT_PROMPTING_ENABLED is not explicitly "false"
|
|
673
|
+
// The main HTTP server always runs, so the endpoint should be available
|
|
674
|
+
if (directPromptingEnabled) {
|
|
675
|
+
logger.info(`🌐 Setting up HTTP prompting endpoints on port ${port}...`);
|
|
660
676
|
await this.setupHttpPromptingEndpoints();
|
|
677
|
+
logger.info("✅ Direct prompting endpoint (/prompt) configured");
|
|
661
678
|
} else {
|
|
662
|
-
logger.warn(`⚠️
|
|
679
|
+
logger.warn(`⚠️ Direct prompting is DISABLED - /prompt endpoint will not be available`);
|
|
680
|
+
logger.warn(` Set DIRECT_PROMPTING_ENABLED=true or call setPromptingServer() to enable`);
|
|
663
681
|
}
|
|
664
|
-
|
|
665
|
-
logger.info("✅ Direct prompting server setup completed");
|
|
666
|
-
}
|
|
667
|
-
|
|
668
|
-
/**
|
|
669
|
-
* Setup WebSocket server for direct prompting
|
|
670
|
-
*/
|
|
671
|
-
async setupWebSocketServer(port) {
|
|
672
|
-
const WebSocket = require("ws");
|
|
673
|
-
const maxConnections =
|
|
674
|
-
parseInt(process.env.DIRECT_PROMPTING_MAX_CONNECTIONS) || 100;
|
|
675
|
-
const authentication =
|
|
676
|
-
process.env.DIRECT_PROMPTING_AUTHENTICATION === "true";
|
|
677
|
-
|
|
678
|
-
this.wsServer = new WebSocket.Server({
|
|
679
|
-
port: port,
|
|
680
|
-
host: "0.0.0.0",
|
|
681
|
-
maxClients: maxConnections,
|
|
682
|
-
});
|
|
683
|
-
|
|
684
|
-
this.activeConnections = 0;
|
|
685
|
-
|
|
686
|
-
logger.info(
|
|
687
|
-
`WebSocket server configured with max ${maxConnections} connections, auth: ${authentication}`
|
|
688
|
-
);
|
|
689
|
-
|
|
690
|
-
this.wsServer.on("connection", (ws, req) => {
|
|
691
|
-
const clientId = require("uuid").v4();
|
|
692
|
-
this.activeConnections++;
|
|
693
|
-
logger.info(
|
|
694
|
-
`WebSocket client connected: ${clientId} (${this.activeConnections}/${maxConnections})`
|
|
695
|
-
);
|
|
696
|
-
|
|
697
|
-
ws.on("message", async (message) => {
|
|
698
|
-
try {
|
|
699
|
-
const data = JSON.parse(message.toString());
|
|
700
|
-
const { prompt, conversationId, metadata } = data;
|
|
701
|
-
|
|
702
|
-
if (!prompt) {
|
|
703
|
-
ws.send(
|
|
704
|
-
JSON.stringify({
|
|
705
|
-
error: "Prompt is required",
|
|
706
|
-
timestamp: new Date().toISOString(),
|
|
707
|
-
})
|
|
708
|
-
);
|
|
709
|
-
return;
|
|
710
|
-
}
|
|
711
|
-
|
|
712
|
-
// Process the prompt with LLM
|
|
713
|
-
const response = await this.processDirectPrompt(prompt, {
|
|
714
|
-
conversationId,
|
|
715
|
-
metadata,
|
|
716
|
-
clientId,
|
|
717
|
-
protocol: "websocket",
|
|
718
|
-
});
|
|
719
|
-
|
|
720
|
-
// Send response back
|
|
721
|
-
ws.send(
|
|
722
|
-
JSON.stringify({
|
|
723
|
-
response: response.content,
|
|
724
|
-
conversationId: conversationId || response.conversationId,
|
|
725
|
-
metadata: response.metadata,
|
|
726
|
-
timestamp: new Date().toISOString(),
|
|
727
|
-
})
|
|
728
|
-
);
|
|
729
|
-
} catch (error) {
|
|
730
|
-
logger.error("WebSocket message processing error:", error);
|
|
731
|
-
ws.send(
|
|
732
|
-
JSON.stringify({
|
|
733
|
-
error: "Failed to process prompt",
|
|
734
|
-
message: error.message,
|
|
735
|
-
timestamp: new Date().toISOString(),
|
|
736
|
-
})
|
|
737
|
-
);
|
|
738
|
-
}
|
|
739
|
-
});
|
|
740
|
-
|
|
741
|
-
ws.on("close", () => {
|
|
742
|
-
this.activeConnections--;
|
|
743
|
-
logger.info(
|
|
744
|
-
`WebSocket client disconnected: ${clientId} (${this.activeConnections}/${maxConnections})`
|
|
745
|
-
);
|
|
746
|
-
});
|
|
747
|
-
|
|
748
|
-
ws.on("error", (error) => {
|
|
749
|
-
logger.error(`WebSocket error for client ${clientId}:`, error);
|
|
750
|
-
});
|
|
751
|
-
});
|
|
752
|
-
|
|
753
|
-
logger.info(`🔌 WebSocket server listening on port ${port}`);
|
|
754
|
-
logger.info(`🔗 Direct prompting endpoint: ws://localhost:${port}`);
|
|
755
682
|
}
|
|
756
683
|
|
|
757
684
|
/**
|
|
758
|
-
* Setup HTTP endpoints for direct prompting
|
|
685
|
+
* Setup HTTP endpoints for direct prompting (adds /prompt endpoint to main app)
|
|
759
686
|
*/
|
|
760
687
|
async setupHttpPromptingEndpoints() {
|
|
761
|
-
logger.info("🔧 Setting up HTTP prompting endpoints...");
|
|
762
|
-
const port = parseInt(process.env.DOCKER_PORT) || 3000;
|
|
763
|
-
logger.info(`Port: ${port}, httpApp exists: ${!!this.httpApp}`);
|
|
764
|
-
|
|
765
|
-
if (!this.httpApp) {
|
|
766
|
-
// Create a minimal HTTP app for prompting if main HTTP is disabled
|
|
767
|
-
logger.info("Creating new Express app for HTTP prompting");
|
|
768
|
-
this.httpApp = express();
|
|
769
|
-
this.httpApp.use(express.json({ limit: "10mb" }));
|
|
770
|
-
}
|
|
688
|
+
logger.info("🔧 Setting up HTTP prompting endpoints on main server...");
|
|
771
689
|
|
|
772
|
-
// Direct prompting endpoint
|
|
773
|
-
this.
|
|
690
|
+
// Direct prompting endpoint on main app
|
|
691
|
+
this.mainApp.post("/prompt", async (req, res) => {
|
|
692
|
+
logger.info(`📥 Received POST /prompt request from ${req.ip || 'unknown'}`);
|
|
774
693
|
try {
|
|
775
694
|
const { prompt, conversationId, metadata } = req.body;
|
|
776
695
|
|
|
@@ -804,34 +723,9 @@ class AgentRuntime {
|
|
|
804
723
|
}
|
|
805
724
|
});
|
|
806
725
|
|
|
807
|
-
|
|
808
|
-
logger.info(
|
|
809
|
-
|
|
810
|
-
);
|
|
811
|
-
|
|
812
|
-
if (!this.httpEnabled) {
|
|
813
|
-
// Only start if main HTTP server is not enabled
|
|
814
|
-
logger.info(`Starting HTTP direct prompting server on port ${port}...`);
|
|
815
|
-
|
|
816
|
-
try {
|
|
817
|
-
const server = this.httpApp.listen(port, "0.0.0.0", () => {
|
|
818
|
-
logger.info(
|
|
819
|
-
`🌐 HTTP direct prompting server listening on port ${port}`
|
|
820
|
-
);
|
|
821
|
-
logger.info(
|
|
822
|
-
`📡 Direct prompting endpoint: POST http://localhost:${port}/prompt`
|
|
823
|
-
);
|
|
824
|
-
});
|
|
825
|
-
|
|
826
|
-
server.on("error", (error) => {
|
|
827
|
-
logger.error(`HTTP server error:`, error);
|
|
828
|
-
});
|
|
829
|
-
} catch (error) {
|
|
830
|
-
logger.error(`Failed to start HTTP server:`, error);
|
|
831
|
-
}
|
|
832
|
-
} else {
|
|
833
|
-
logger.info(`📡 HTTP prompting endpoint added: POST /prompt`);
|
|
834
|
-
}
|
|
726
|
+
logger.info(`📡 HTTP prompting endpoint added: POST /prompt`);
|
|
727
|
+
logger.info(` Full URL: http://localhost:${this.mainPort}/prompt`);
|
|
728
|
+
logger.info(` Full URL: http://127.0.0.1:${this.mainPort}/prompt`);
|
|
835
729
|
}
|
|
836
730
|
|
|
837
731
|
/**
|
|
@@ -948,113 +842,6 @@ class AgentRuntime {
|
|
|
948
842
|
}
|
|
949
843
|
}
|
|
950
844
|
|
|
951
|
-
/**
|
|
952
|
-
* Wrap HTTP handler to emit tool events
|
|
953
|
-
*/
|
|
954
|
-
wrapHttpHandlerWithEvents(method, path, originalHandler) {
|
|
955
|
-
return async (req, res) => {
|
|
956
|
-
const startTime = Date.now();
|
|
957
|
-
const requestId = require("uuid").v4();
|
|
958
|
-
|
|
959
|
-
try {
|
|
960
|
-
// Emit call event
|
|
961
|
-
this.emitEvent("tool:http-server:call", {
|
|
962
|
-
requestId,
|
|
963
|
-
method: method.toUpperCase(),
|
|
964
|
-
path,
|
|
965
|
-
headers: req.headers,
|
|
966
|
-
body: req.body,
|
|
967
|
-
query: req.query,
|
|
968
|
-
params: req.params,
|
|
969
|
-
timestamp: new Date().toISOString(),
|
|
970
|
-
});
|
|
971
|
-
|
|
972
|
-
// Emit specific method call event
|
|
973
|
-
this.emitEvent(`tool:http-server:call:${method.toLowerCase()}`, {
|
|
974
|
-
requestId,
|
|
975
|
-
path,
|
|
976
|
-
headers: req.headers,
|
|
977
|
-
body: req.body,
|
|
978
|
-
query: req.query,
|
|
979
|
-
params: req.params,
|
|
980
|
-
timestamp: new Date().toISOString(),
|
|
981
|
-
});
|
|
982
|
-
|
|
983
|
-
// Capture response data
|
|
984
|
-
const originalSend = res.send;
|
|
985
|
-
const originalJson = res.json;
|
|
986
|
-
let responseData = null;
|
|
987
|
-
let statusCode = 200;
|
|
988
|
-
|
|
989
|
-
res.send = function (data) {
|
|
990
|
-
responseData = data;
|
|
991
|
-
statusCode = res.statusCode;
|
|
992
|
-
return originalSend.call(this, data);
|
|
993
|
-
};
|
|
994
|
-
|
|
995
|
-
res.json = function (data) {
|
|
996
|
-
responseData = data;
|
|
997
|
-
statusCode = res.statusCode;
|
|
998
|
-
return originalJson.call(this, data);
|
|
999
|
-
};
|
|
1000
|
-
|
|
1001
|
-
// Execute original handler
|
|
1002
|
-
const result = await originalHandler(req, res);
|
|
1003
|
-
|
|
1004
|
-
const processingTime = Date.now() - startTime;
|
|
1005
|
-
|
|
1006
|
-
// Emit response event
|
|
1007
|
-
this.emitEvent("tool:http-server:response", {
|
|
1008
|
-
requestId,
|
|
1009
|
-
method: method.toUpperCase(),
|
|
1010
|
-
path,
|
|
1011
|
-
statusCode,
|
|
1012
|
-
responseData,
|
|
1013
|
-
processingTime,
|
|
1014
|
-
timestamp: new Date().toISOString(),
|
|
1015
|
-
});
|
|
1016
|
-
|
|
1017
|
-
// Emit specific method response event
|
|
1018
|
-
this.emitEvent(`tool:http-server:response:${method.toLowerCase()}`, {
|
|
1019
|
-
requestId,
|
|
1020
|
-
path,
|
|
1021
|
-
statusCode,
|
|
1022
|
-
responseData,
|
|
1023
|
-
processingTime,
|
|
1024
|
-
timestamp: new Date().toISOString(),
|
|
1025
|
-
});
|
|
1026
|
-
|
|
1027
|
-
// Emit wildcard events
|
|
1028
|
-
this.emitEvent("tool:http-server:*", {
|
|
1029
|
-
type: "response",
|
|
1030
|
-
requestId,
|
|
1031
|
-
method: method.toUpperCase(),
|
|
1032
|
-
path,
|
|
1033
|
-
statusCode,
|
|
1034
|
-
responseData,
|
|
1035
|
-
processingTime,
|
|
1036
|
-
timestamp: new Date().toISOString(),
|
|
1037
|
-
});
|
|
1038
|
-
|
|
1039
|
-
return result;
|
|
1040
|
-
} catch (error) {
|
|
1041
|
-
const processingTime = Date.now() - startTime;
|
|
1042
|
-
|
|
1043
|
-
// Emit error event
|
|
1044
|
-
this.emitEvent("tool:http-server:error", {
|
|
1045
|
-
requestId,
|
|
1046
|
-
method: method.toUpperCase(),
|
|
1047
|
-
path,
|
|
1048
|
-
error: error.message,
|
|
1049
|
-
stack: error.stack,
|
|
1050
|
-
processingTime,
|
|
1051
|
-
timestamp: new Date().toISOString(),
|
|
1052
|
-
});
|
|
1053
|
-
|
|
1054
|
-
throw error;
|
|
1055
|
-
}
|
|
1056
|
-
};
|
|
1057
|
-
}
|
|
1058
845
|
|
|
1059
846
|
/**
|
|
1060
847
|
* Create tools proxy for agent runtime
|