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
26 changes: 26 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: Build
on:
push:
branches:
- dev
- testing
- wip
- main
pull_request:
types: [opened, synchronize, reopened]
jobs:
sonarqube:
name: SonarQube
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
- name: SonarQube Scan
uses: SonarSource/sonarqube-scan-action@v5
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
with:
args:
-Dsonar.projectKey=${{ secrets.SONAR_PROJECT_KEY }}
-Dsonar.organization=${{ secrets.SONAR_ORGANIZATION }}
File renamed without changes.
11 changes: 10 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
tim-db
.vscode/
.idea/
# Node modules
node_modules/

#Common .ignore files
*.DS_Store
*.log
# MLflow generated files
mlflow_artifacts/
mlflow_data/
Expand All @@ -22,4 +31,4 @@ logs/
test/logs/
**/logs/
*.log.*
*.zip
*.zip
2 changes: 2 additions & 0 deletions DSL/Resql/global-classifier/GET/empty.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
-- This is a empty sql for Buerokratt DSL delivery method
SELECT current_date;
12 changes: 12 additions & 0 deletions DSL/Resql/global-classifier/POST/store-classification-feedback.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
INSERT INTO classification_feedback (
chat_id,
inference_id,
actual_agency_id
)
VALUES (
:chatId,
:inferenceId,
:actualAgencyId,
:feedback_timestamp::timestamp
)
RETURNING id, chat_id, inference_id, feedback_timestamp;
13 changes: 13 additions & 0 deletions DSL/Resql/global-classifier/POST/store-classification.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
INSERT INTO classification_results (
chat_id,
inference_id,
target_agencies,
classification_timestamp
)
VALUES (
:chatId,
:inferenceId,
:targetAgencies::jsonb,
CURRENT_TIMESTAMP
)
RETURNING id, chat_id, inference_id, classification_timestamp;
73 changes: 73 additions & 0 deletions DSL/Ruuter.public/global-classifier/POST/chats/classify.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
declaration:
call: declare
version: 0.1
description: "Callback endpoint for Global Classifier to indicate routing decisions"
method: post
accepts: json
returns: json
namespace: global-classifier
allowlist:
body:
- field: chatId
type: string
description: "Unique identifier of the chat session"
- field: inferenceId
type: string
description: "Unique identifier of the prediction attempt"
- field: targetAgencies
type: json
description: "Array of agency IDs with confidence scores for routing"

extractDecisionData:
assign:
chatId: ${incoming.body.chatId}
inferenceId: ${incoming.body.inferenceId}
targetAgencies: ${incoming.body.targetAgencies ?? []}
next: validate_decision

validate_decision:
switch:
- condition: ${!chatId}
next: return_validation_error
next: log_classification

return_validation_error:
status: 400
return: "Invalid classification payload. Chat ID is required."
next: end

log_classification:
log: "Classification received for the chat ${chatId}: ${JSON.stringify(targetAgencies)}"
next: store_classification_data

store_classification_data:
call: http.post
args:
url: "[#GLOBAL_CLASSIFIER_RESQL]/store-classification"
body:
chatId: ${chatId}
inferenceId: ${inferenceId}
targetAgencies: ${JSON.stringify(targetAgencies)}
result: store_result
error: handle_storage_error
next: check_storage_result

check_storage_result:
switch:
- condition: ${200 <= store_result.response.statusCodeValue && store_result.response.statusCodeValue < 300}
next: return_success
next: handle_storage_error

handle_storage_error:
log: "Error storing classification data: ${store_result.error}"
next: return_storage_error

return_storage_error:
status: 500
return: "Failed to store classification data. Please try again later."
next: end

return_success:
status: 200
return: "Classification received and stored successfully"
next: end
79 changes: 79 additions & 0 deletions DSL/Ruuter.public/global-classifier/POST/chats/feedback.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
declaration:
call: declare
version: 0.1
description: "Endpoint to receive feedback on global classifier predictions"
method: post
accepts: json
returns: json
namespace: global-classifier
allowlist:
body:
- field: chatId
type: string
description: "ID of the chat that was classified"
- field: inferenceId
type: string
description: "Unique identifier of the classification prediction"
- field: actualAgencyId
type: string
description: "The agency that actually handled the request"

extractFeedbackData:
assign:
chatId: ${incoming.body.chatId}
inferenceId: ${incoming.body.inferenceId}
actualAgencyId: ${incoming.body.actualAgencyId ?? ""}
timestamp: ${new Date().toISOString()}
next: validate_feedback

validate_feedback:
switch:
- condition: ${!chatId || inferenceId === undefined}
next: return_validation_error
next: log_feedback

return_validation_error:
status: 400
return: "Invalid feedback payload. chatId, inferenceId are required fields."
next: end

log_feedback:
log: "Classification feedback received for chat ${chatId}"
next: store_feedback

store_feedback:
call: http.post
args:
url: "[#GLOBAL_CLASSIFIER_RESQL]/store-classification-feedback"
body:
chatId: ${chatId}
inferenceId: ${inferenceId}
actualAgencyId: ${actualAgencyId}
result: store_result
error: handle_storage_error
next: check_storage_result

check_storage_result:
switch:
- condition: ${200 <= store_result.response.statusCodeValue && store_result.response.statusCodeValue < 300}
next: process_feedback_for_model
next: return_storage_error

process_feedback_for_model:
log: "Feedback stored successfully and will be used for model improvement"
next: return_success

handle_storage_error:
log: "Error storing feedback: ${store_result.error}"
next: return_storage_error

return_storage_error:
status: 500
return: "Failed to store feedback. Please try again later."
next: end

return_success:
status: 200
return: "Feedback received and processed successfully"
next: end

68 changes: 68 additions & 0 deletions DSL/Ruuter.public/global-classifier/POST/chats/incoming.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
declaration:
call: declare
version: 0.1
description: "Global classifier service to receive incoming chat messages and classify them."
method: post
accepts: json
returns: json
namespace: global-classifier
allowlist:
body:
- field: chatId
type: string
description: "Chat session identifier"
- field: message
type: string
description: "The user message content to classify"
- field: authorId
type: string
description: "Buerokrat chat bot ID"
- field: conversationHistory
type: json
description: "Previous messages in the conversation for context"
- field: url
type: string
description: "Additional url that might help with classification"

extractRequestData:
assign:
chatId: ${incoming.body.chatId}
message: ${incoming.body.message ?? ""}
authorId: ${incoming.body.authorId ?? ""}
conversationHistory: ${incoming.body.conversationHistory ?? []}
url: ${incoming.body.url}
next: log_classification_request

log_classification_request:
log: "Classification request received for chat ${chatId}: ${message}"
next: forward_to_classifier_service

forward_to_classifier_service:
call: http.post
args:
url: "[#CHATBOT_CLASSIFIER_SERVICE]/incoming-conversation"
body:
chatId: ${chatId}
message: ${message}
authorId: ${authorId}
conversationHistory: ${conversationHistory}
url: ${url}
timestamp: ${new Date().toISOString()}
result: classifier_result
error: return_error
next: process_classification_result

process_classification_result:
switch:
- condition: ${classifier_result.response.body.suggestedBot != null}
next: return_suggestion

return_suggestion:
status: 200
return: ${classifier_result.response.body}
next: end

return_error:
status: 500
return: "Classification service unavailable"
next: end
Loading