Spaces:
Sleeping
Sleeping
| # Model Orchestrator Service β API Documentation | |
| **Version**: 1.0 | |
| **Base URL**: `http://localhost:8090` (local) β configured via `SERVICE_RUNTIME_HOST` | |
| **Content-Type**: `application/json` | |
| --- | |
| ## Authentication | |
| All endpoints under `/api/*` require a JWT Bearer token. | |
| ``` | |
| Authorization: Bearer <JWT_TOKEN> | |
| ``` | |
| The token must contain the following claims: `TenantId`, `UserId`, `Email`, `UniqueName`, `FullName`. | |
| --- | |
| ## Response Format | |
| ### Success | |
| All successful responses are wrapped in a consistent envelope: | |
| ```json | |
| { | |
| "data": { ... } | |
| } | |
| ``` | |
| ### Error | |
| ```json | |
| { | |
| "error_message": "Human-readable description", | |
| "error_code": "machine.readable.code" | |
| } | |
| ``` | |
| ### HTTP Status Codes | |
| | Code | Meaning | | |
| |------|---------| | |
| | 200 | Success | | |
| | 400 | Bad request / validation error | | |
| | 401 | Unauthorized β missing or invalid token | | |
| | 500 | Internal server error | | |
| --- | |
| ## Endpoints Overview | |
| | Method | Path | Description | Auth | | |
| |--------|------|-------------|------| | |
| | GET | `/health/ready` | Readiness probe | No | | |
| | GET | `/health/live` | Liveness probe | No | | |
| | GET | `/api/room` | Get all rooms | Yes | | |
| | PUT | `/api/room/:room_id` | Update room name | Yes | | |
| | PATCH | `/api/room/:room_id` | Delete a room | Yes | | |
| | GET | `/api/room/:room_id/chat` | Get all chats in a room | Yes | | |
| | POST | `/api/chat` | Create a new chat | Yes | | |
| | POST | `/api/chat/:chat_id/retry` | Retry a failed chat | Yes | | |
| | GET | `/api/chat/:chat_id/status` | Get chat processing status | Yes | | |
| | POST | `/api/chat/:chat_id/feedback` | Submit feedback for a chat | Yes | | |
| | GET | `/api/chatbot/helper_prompt` | Get equipment helper prompts | Yes | | |
| --- | |
| ## Health | |
| ### GET `/health/ready` | |
| Returns `200 Ok` when the service is ready to receive traffic. No auth required. | |
| ### GET `/health/live` | |
| Returns `200 Ok` when the service process is alive. No auth required. | |
| --- | |
| ## Room | |
| Rooms are conversation containers. Each room holds a list of chat exchanges belonging to a user. | |
| --- | |
| ### GET `/api/room` | |
| Get all rooms belonging to the authenticated user. | |
| **Request**: No body, no query parameters. | |
| **Response `200`**: | |
| ```json | |
| { | |
| "data": [ | |
| { | |
| "id": "string", | |
| "name": "string" | |
| } | |
| ] | |
| } | |
| ``` | |
| | Field | Type | Description | | |
| |-------|------|-------------| | |
| | `id` | string | Unique room identifier | | |
| | `name` | string | Display name of the room | | |
| **Error responses**: | |
| | Code | `error_code` | Description | | |
| |------|-------------|-------------| | |
| | 500 | `modelorchestrator.room.get.error` | Failed to retrieve rooms | | |
| --- | |
| ### PUT `/api/room/:room_id` | |
| Rename an existing room. | |
| **Path parameter**: | |
| | Parameter | Type | Required | Description | | |
| |-----------|------|----------|-------------| | |
| | `room_id` | string | Yes | ID of the room to update | | |
| **Request body**: | |
| ```json | |
| { | |
| "name": "string" | |
| } | |
| ``` | |
| | Field | Type | Required | Description | | |
| |-------|------|----------|-------------| | |
| | `name` | string | Yes | New name for the room | | |
| **Response `200`**: | |
| ```json | |
| { | |
| "data": { | |
| "room_id": "string" | |
| } | |
| } | |
| ``` | |
| **Error responses**: | |
| | Code | `error_code` | Description | | |
| |------|-------------|-------------| | |
| | 400 | `modelorchestrator.room.update.errorvalidation` | Invalid or missing request body | | |
| | 500 | `modelorchestrator.room.update.error` | Failed to update room | | |
| --- | |
| ### PATCH `/api/room/:room_id` | |
| Soft-delete a room. | |
| **Path parameter**: | |
| | Parameter | Type | Required | Description | | |
| |-----------|------|----------|-------------| | |
| | `room_id` | string | Yes | ID of the room to delete | | |
| **Request body**: None | |
| **Response `200`**: | |
| ```json | |
| { | |
| "data": { | |
| "room_id": "string" | |
| } | |
| } | |
| ``` | |
| **Error responses**: | |
| | Code | `error_code` | Description | | |
| |------|-------------|-------------| | |
| | 500 | `modelorchestrator.room.delete.error` | Failed to delete room | | |
| --- | |
| ### GET `/api/room/:room_id/chat` | |
| Get the full chat history for a specific room. | |
| **Path parameter**: | |
| | Parameter | Type | Required | Description | | |
| |-----------|------|----------|-------------| | |
| | `room_id` | string | Yes | ID of the room | | |
| **Request body**: None | |
| **Response `200`**: | |
| ```json | |
| { | |
| "data": [ | |
| { | |
| "id": "string", | |
| "question": "any", | |
| "answer_text": "any | null", | |
| "status": "string", | |
| "feedback_status": "string | null", | |
| "feedback_reason": "string | null" | |
| } | |
| ] | |
| } | |
| ``` | |
| | Field | Type | Nullable | Description | | |
| |-------|------|----------|-------------| | |
| | `id` | string | No | Chat entry ID | | |
| | `question` | any | No | The question that was submitted (can be string or object) | | |
| | `answer_text` | any | Yes | The answer returned by the AI. `null` if still processing | | |
| | `status` | string | No | Processing status of the chat. See [Chat Status Values](#chat-status-values) | | |
| | `feedback_status` | string | Yes | Feedback given by user, if any | | |
| | `feedback_reason` | string | Yes | Reason for the feedback, if any | | |
| **Error responses**: | |
| | Code | `error_code` | Description | | |
| |------|-------------|-------------| | |
| | 500 | `modelorchestrator.room.chat.error` | Failed to retrieve room chats | | |
| --- | |
| ## Chat | |
| A chat represents a single questionβanswer exchange within a room. Creating a chat triggers the AI processing asynchronously β use the status endpoint to poll for completion. | |
| --- | |
| ### POST `/api/chat` | |
| Create a new chat (submit a question to the AI). | |
| If `room_id` is empty, a new room will be created automatically and its ID is returned in the response. | |
| **Request body**: | |
| ```json | |
| { | |
| "agent": "string", | |
| "req_plot_object": false, | |
| "room_id": "string", | |
| "question": "any" | |
| } | |
| ``` | |
| | Field | Type | Required | Description | | |
| |-------|------|----------|-------------| | |
| | `agent` | string | Yes | Identifier of the AI agent to use | | |
| | `req_plot_object` | boolean | Yes | Set `true` if the response should include a plot/chart object | | |
| | `room_id` | string | Yes | ID of the room to post the chat in. Pass an empty string `""` to auto-create a room | | |
| | `question` | any | Yes | The question or prompt. Can be a plain string or a structured object depending on the agent | | |
| **Response `200`**: | |
| ```json | |
| { | |
| "data": { | |
| "room_id": "string", | |
| "room_name": "string", | |
| "chat_id": "string" | |
| } | |
| } | |
| ``` | |
| | Field | Type | Description | | |
| |-------|------|-------------| | |
| | `room_id` | string | The room this chat belongs to (auto-generated if not provided) | | |
| | `room_name` | string | Display name of the room | | |
| | `chat_id` | string | ID of the newly created chat. Use this to poll status and submit feedback | | |
| **Error responses**: | |
| | Code | `error_code` | Description | | |
| |------|-------------|-------------| | |
| | 400 | `modelorchestrator.chat.create.errorvalidation` | Invalid or missing request body | | |
| | 500 | `modelorchestrator.chat.create.error` | Failed to create chat | | |
| --- | |
| ### POST `/api/chat/:chat_id/retry` | |
| Retry a chat that failed or got stuck. Resubmits the original question. | |
| **Path parameter**: | |
| | Parameter | Type | Required | Description | | |
| |-----------|------|----------|-------------| | |
| | `chat_id` | string | Yes | ID of the chat to retry | | |
| **Request body**: None | |
| **Response `200`**: | |
| ```json | |
| { | |
| "data": { | |
| "room_id": "string", | |
| "chat_id": "string" | |
| } | |
| } | |
| ``` | |
| **Error responses**: | |
| | Code | `error_code` | Description | | |
| |------|-------------|-------------| | |
| | 500 | `modelorchestrator.chat.retry.error` | Failed to retry chat | | |
| --- | |
| ### GET `/api/chat/:chat_id/status` | |
| Poll the processing status of a chat. Use this after creating a chat to determine when the answer is ready. | |
| **Path parameter**: | |
| | Parameter | Type | Required | Description | | |
| |-----------|------|----------|-------------| | |
| | `chat_id` | string | Yes | ID of the chat | | |
| **Request body**: None | |
| **Response `200`**: | |
| ```json | |
| { | |
| "data": { | |
| "chat_id": "string", | |
| "status": "string" | |
| } | |
| } | |
| ``` | |
| **Error responses**: | |
| | Code | `error_code` | Description | | |
| |------|-------------|-------------| | |
| | 500 | `modelorchestrator.chat.getstatus.error` | Failed to retrieve chat status | | |
| #### Chat Status Values | |
| | Status | Description | | |
| |--------|-------------| | |
| | `pending` | Chat has been created, waiting to be processed | | |
| | `processing` | AI is currently generating a response | | |
| | `completed` | Response is ready β fetch via `GET /api/room/:room_id/chat` | | |
| | `failed` | Processing failed β use retry endpoint | | |
| > **Polling recommendation**: Poll every 2β3 seconds. Stop when status is `completed` or `failed`. | |
| --- | |
| ### POST `/api/chat/:chat_id/feedback` | |
| Submit user feedback (thumbs up/down and reason) for a completed chat. | |
| **Path parameter**: | |
| | Parameter | Type | Required | Description | | |
| |-----------|------|----------|-------------| | |
| | `chat_id` | string | Yes | ID of the chat to give feedback on | | |
| **Request body**: | |
| ```json | |
| { | |
| "status": "string", | |
| "reason": "string" | |
| } | |
| ``` | |
| | Field | Type | Required | Description | | |
| |-------|------|----------|-------------| | |
| | `status` | string | Yes | Feedback rating (e.g. `"positive"`, `"negative"`) | | |
| | `reason` | string | Yes | Explanation for the feedback | | |
| **Response `200`**: | |
| ```json | |
| { | |
| "data": { | |
| "id": "string" | |
| } | |
| } | |
| ``` | |
| | Field | Type | Description | | |
| |-------|------|-------------| | |
| | `id` | string | ID of the created feedback record | | |
| **Error responses**: | |
| | Code | `error_code` | Description | | |
| |------|-------------|-------------| | |
| | 400 | `modelorchestrator.chat.createfeedback.errorvalidation` | Invalid or missing request body | | |
| | 500 | `modelorchestrator.chat.createfeedback.error` | Failed to submit feedback | | |
| --- | |
| ## Chatbot | |
| ### GET `/api/chatbot/helper_prompt` | |
| Get a structured list of equipment suggestions to help users construct prompts. The response is a 4-level nested map: `site_id β section β model β eqm_no β [equipment list]`. | |
| **Query parameters**: | |
| | Parameter | Type | Required | Description | | |
| |-----------|------|----------|-------------| | |
| | `topic` | string | Yes | Topic category. Must be one of the allowed values below | | |
| | `year` | integer | Yes | The year to filter data by (e.g. `2024`) | | |
| **Allowed `topic` values**: | |
| | Value | Description | | |
| |-------|-------------| | |
| | `pa performance` | PA performance analysis | | |
| | `bad actor` | Bad actor identification | | |
| | `pareto` | Pareto analysis | | |
| | `inspection` | Inspection data | | |
| | `backlog` | Maintenance backlog | | |
| | `planning` | Planning analysis | | |
| | `execution` | Execution analysis | | |
| **Response `200`**: | |
| ```json | |
| { | |
| "data": { | |
| "<site_id>": { | |
| "<section>": { | |
| "<model>": { | |
| "<eqm_no>": ["equipment_name_1", "equipment_name_2"] | |
| } | |
| } | |
| } | |
| } | |
| } | |
| ``` | |
| **Example**: | |
| ```json | |
| { | |
| "data": { | |
| "SITE_A": { | |
| "MECHANICAL": { | |
| "PUMP": { | |
| "P-001": ["P-001A", "P-001B"] | |
| } | |
| } | |
| } | |
| } | |
| } | |
| ``` | |
| **Error responses**: | |
| | Code | `error_code` | Description | | |
| |------|-------------|-------------| | |
| | 400 | `helper.prompt.validation.topic` | `topic` is missing or not one of the allowed values | | |
| | 400 | `helper.prompt.validation.year` | `year` query parameter is missing | | |
| | 400 | `helper.prompt.validation.year.format` | `year` is not a valid integer | | |
| | 500 | `helper.prompt.service.error` | Failed to retrieve helper prompt data | | |
| --- | |
| ## Typical Frontend Flow | |
| Below is the recommended sequence for a full chat interaction: | |
| ``` | |
| 1. GET /api/room β fetch existing rooms for sidebar | |
| 2. POST /api/chat β submit question (use room_id="" for new room) | |
| β returns { room_id, room_name, chat_id } | |
| 3. GET /api/chat/:chat_id/status β poll every 2β3s until status = "completed" or "failed" | |
| 4. GET /api/room/:room_id/chat β fetch full chat history including the answer | |
| 5. POST /api/chat/:chat_id/feedback β (optional) submit user rating | |
| 6. POST /api/chat/:chat_id/retry β (if status = "failed") retry | |
| ``` | |
| --- | |
| ## Error Code Reference | |
| All error responses follow this format: | |
| ```json | |
| { | |
| "error_message": "Human-readable description", | |
| "error_code": "machine.readable.code" | |
| } | |
| ``` | |
| ### Authentication Errors | |
| These errors are returned before any endpoint logic runs, when the JWT token is missing, malformed, or invalid. | |
| | HTTP | `error_code` | `error_message` | Cause | | |
| |------|-------------|-----------------|-------| | |
| | 401 | `error.cred.missing` | Authorization creds missing | `Authorization` header not present in request | | |
| | 401 | `error.cred.incomplete` | Authorization cred incomplete | Header present but not in `Bearer <token>` format | | |
| | 401 | `error.cred.invalid` | Authorization cred invalid | JWT token cannot be parsed or is malformed | | |
| | 401 | `error.cred.missingAttribute` | Authorization cred attribute missing | Token is valid but missing required claims (`tenantId` or `userId`) | | |
| | 401 | `error.database.connectionfailure` | Unable to establish connection to tenant database | Service could not open a DB connection for the tenant derived from the token | | |
| ### Room Errors | |
| | HTTP | `error_code` | `error_message` | Endpoint | Cause | | |
| |------|-------------|-----------------|----------|-------| | |
| | 500 | `modelorchestrator.room.gettenant.error` | Unable to get tenant context | All room endpoints | Internal error reading tenant context from middleware | | |
| | 400 | `modelorchestrator.room.update.errorvalidation` | Unable to read input | `PUT /api/room/:room_id` | Request body is missing or not valid JSON | | |
| | 500 | `modelorchestrator.room.update.error` | Unable to update room | `PUT /api/room/:room_id` | Database error while updating the room | | |
| | 500 | `modelorchestrator.room.delete.error` | Unable to get room chats | `PATCH /api/room/:room_id` | Database error while deleting the room | | |
| | 500 | `modelorchestrator.room.get.error` | Unable to get rooms | `GET /api/room` | Database error while fetching room list | | |
| | 500 | `modelorchestrator.room.chat.error` | Unable to get room chats | `GET /api/room/:room_id/chat` | Database error while fetching chat history | | |
| ### Chat Errors | |
| | HTTP | `error_code` | `error_message` | Endpoint | Cause | | |
| |------|-------------|-----------------|----------|-------| | |
| | 500 | `modelorchestrator.chat.gettenant.error` | Unable to get tenant context | All chat endpoints | Internal error reading tenant context from middleware | | |
| | 400 | `modelorchestrator.chat.create.errorvalidation` | Unable to read input | `POST /api/chat` | Request body is missing or not valid JSON | | |
| | 500 | `modelorchestrator.chat.create.error` | Unable to create chat | `POST /api/chat` | Database error while creating the chat record | | |
| | 500 | `modelorchestrator.chat.retry.error` | Unable to retry chat | `POST /api/chat/:chat_id/retry` | Chat not found or database error during retry | | |
| | 500 | `modelorchestrator.chat.getstatus.error` | Unable to get chat status | `GET /api/chat/:chat_id/status` | Database error while fetching chat status | | |
| | 400 | `modelorchestrator.chat.createfeedback.errorvalidation` | Unable to read input | `POST /api/chat/:chat_id/feedback` | Request body is missing or not valid JSON | | |
| | 500 | `modelorchestrator.chat.createfeedback.error` | Unable to get chat status | `POST /api/chat/:chat_id/feedback` | Database error while saving feedback | | |
| ### Chatbot Errors | |
| | HTTP | `error_code` | `error_message` | Endpoint | Cause | | |
| |------|-------------|-----------------|----------|-------| | |
| | 500 | `modelorchestrator.prompt.gettenant.error` | Unable to get tenant context | `GET /api/chatbot/helper_prompt` | Internal error reading tenant context from middleware | | |
| | 400 | `helper.prompt.validation.topic` | Invalid topic provided | `GET /api/chatbot/helper_prompt` | `topic` query param is missing or not one of the 7 allowed values | | |
| | 400 | `helper.prompt.validation.year` | Year is required | `GET /api/chatbot/helper_prompt` | `year` query param is not provided | | |
| | 400 | `helper.prompt.validation.year.format` | Invalid year format | `GET /api/chatbot/helper_prompt` | `year` query param is not a valid integer | | |
| | 500 | `helper.prompt.service.error` | Failed to get helper prompt | `GET /api/chatbot/helper_prompt` | Database error while fetching helper prompt data | | |
| ### System Errors | |
| | HTTP | `error_code` | `error_message` | Cause | | |
| |------|-------------|-----------------|-------| | |
| | 500 | `error.internalservererror` | Internal Server Error | Unhandled panic in the service β logged server-side with full stack trace | | |
| --- | |
| ## CORS | |
| CORS is enabled globally. All origins are allowed and credentials are supported. | |
| ``` | |
| Access-Control-Allow-Origin: * | |
| Access-Control-Allow-Credentials: true | |
| Access-Control-Allow-Methods: POST, OPTIONS, GET, PUT, PATCH | |
| ``` | |