updates on the ai agents and time series prediction and updates on the api to

This commit is contained in:
2026-10-09 13:50:30 +05:30
parent 29690c56f2
commit 153be40e5c
42 changed files with 4889 additions and 186 deletions

View File

@@ -415,6 +415,13 @@ func RegisterRoutes(app *fiber.App, cfg *config.Config) {
adminAuth.Put("/bookings/:id/status", controllers.AdminUpdateBookingStatus)
adminAuth.Post("/bookings/:id/cancel", controllers.AdminCancelBooking)
adminAuth.Post("/bookings/bulk-cancel", controllers.AdminBulkCancelBookings)
// Batch assign, admin side. The same solver /hub/bookings/batch-assign
// uses (controllers/batchAssignService.go), with admin auth and scoped to
// the login's own tenant. This is what backs the console ops layer's
// `assignMiler` proposal, which had no executor because the hub route
// 403s for every admin token and /bookings/:id/assign-miler needs a rider
// the finding does not pick.
adminAuth.Post("/bookings/batch-assign", middlewares.DoormileStaffOnly, controllers.AdminBatchAssign)
// Consignments
adminAuth.Get("/consignments", controllers.GetAdminConsignments)
@@ -486,6 +493,23 @@ func RegisterRoutes(app *fiber.App, cfg *config.Config) {
aiRegistry.Patch("/skills/:id", middlewares.RoleCheckMiddleware(1), controllers.PatchAISkill)
aiRegistry.Get("/tools", controllers.GetAITools)
aiRegistry.Get("/audit", controllers.GetAIRegistryAudit)
// What the console's rule skills have been noticing. The findings used to
// exist for one render in the operator's browser and then vanish, so
// nothing could say whether a skill was useful or whether acting on a
// finding cleared it. Writes are open to the same roles as reads here:
// the console reports what it evaluated, it is not an operator action.
aiRegistry.Get("/findings", controllers.GetAIFindings)
aiRegistry.Get("/findings/stats", controllers.GetAIFindingStats)
aiRegistry.Post("/findings", controllers.UpsertAIFindings)
aiRegistry.Post("/findings/:fingerprint/acted", controllers.RecordAIFindingActed)
// Tomorrow's expected pickups per zone, with the staffing gap against
// riders actually on duty. A bare forecast number is not actionable — the
// gap is (docs/prediction-plan.md §2.4).
aiRegistry.Get("/forecast/demand", controllers.GetDemandForecast)
// The engine's live agent state, proxied. The console's Agents page cannot
// reach :8700 itself (ClusterIP, and it is a browser). A 503 here means
// "use the snapshot", not "broken" — see the controller.
aiRegistry.Get("/engine/agents", controllers.GetAIEngineAgents)
// What the agents did (Phase 4): runs from AI_engine telemetry, decisions
// from agent_decisions, live heartbeat from Redis. Read-only.
aiRegistry.Get("/insights", controllers.GetAIInsights)
@@ -591,10 +615,19 @@ func RegisterRoutes(app *fiber.App, cfg *config.Config) {
internal.Post("/notify", controllers.InternalNotify)
internal.Post("/bookings/:id/reassign", controllers.InternalReassign)
internal.Post("/agent-decisions", controllers.CreateAgentDecision)
internal.Get("/agent-decisions/similar", controllers.FindSimilarDecisions)
// POST, not GET: the handler needs a 1536-float embedding in the body, and
// a GET with a body is dropped by nginx and most HTTP clients — and this
// API is served THROUGH host nginx today (conf/nginx-doormile.conf), so it
// would not merely be risky, it would not work. Nothing called it while it
// was a GET, so changing the method breaks no caller.
internal.Post("/agent-decisions/similar", controllers.FindSimilarDecisions)
internal.Patch("/agent-decisions/:id/outcome", controllers.UpdateDecisionOutcome)
// The agent registry, for AI_engine to poll (ETag / If-None-Match → 304).
internal.Get("/ai/registry", controllers.GetInternalAIRegistry)
// The demand forecast, written by AI_engine's forecast job. The model lives
// in Python (prophet where it beats a seasonal baseline, the baseline
// otherwise); the backend stores and serves it.
internal.Post("/demand-forecast", controllers.UpsertDemandForecast)
// Express-batch dispatch: the ExpressDispatchAgent reads a tenant's riders
// and the batch's bookings, then writes back the assignments it decided.