Harden vehicle detection and prompt
All checks were successful
build-and-deploy / build-deploy (push) Successful in 32s
All checks were successful
build-and-deploy / build-deploy (push) Successful in 32s
This commit is contained in:
@@ -25,14 +25,22 @@ class DocumentExtractionService(
|
|||||||
imageUrl,
|
imageUrl,
|
||||||
"IS THIS A VEHICLE NUMBER PLATE PHOTO? Answer YES or NO only."
|
"IS THIS A VEHICLE NUMBER PLATE PHOTO? Answer YES or NO only."
|
||||||
)
|
)
|
||||||
isYes(results["isVehiclePhoto"])
|
if (!isYes(results["isVehiclePhoto"])) return@Detection false
|
||||||
},
|
val candidate = llamaClient.ask(
|
||||||
handle = {
|
|
||||||
results["vehicleNumber"] = llamaClient.ask(
|
|
||||||
imageUrl,
|
imageUrl,
|
||||||
"VEHICLE NUMBER PLATE? Reply only number or NONE."
|
"VEHICLE NUMBER PLATE? Reply only number or NONE."
|
||||||
)
|
)
|
||||||
|
val cleaned = cleanedValue(candidate)
|
||||||
|
if (cleaned != null && isLikelyVehicleNumber(cleaned)) {
|
||||||
|
results["vehicleNumber"] = cleaned
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
results["vehicleNumber"] = "NONE"
|
||||||
|
results["isVehiclePhoto"] = "NO"
|
||||||
|
false
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
handle = {}
|
||||||
),
|
),
|
||||||
Detection(
|
Detection(
|
||||||
detect = {
|
detect = {
|
||||||
@@ -217,6 +225,13 @@ class DocumentExtractionService(
|
|||||||
return value.orEmpty().contains("YES", ignoreCase = true)
|
return value.orEmpty().contains("YES", ignoreCase = true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun isLikelyVehicleNumber(value: String): Boolean {
|
||||||
|
val normalized = value.uppercase().replace(Regex("[\\s-]"), "")
|
||||||
|
if (normalized.length == 12 && normalized.all { it.isDigit() }) return false
|
||||||
|
if (normalized.length < 6) return false
|
||||||
|
return standardPlateRegex.matches(normalized) || bhPlateRegex.matches(normalized)
|
||||||
|
}
|
||||||
|
|
||||||
private fun computeDocType(results: Map<String, String>, handled: Boolean): String {
|
private fun computeDocType(results: Map<String, String>, handled: Boolean): String {
|
||||||
if (!handled) return "GENERAL"
|
if (!handled) return "GENERAL"
|
||||||
return when {
|
return when {
|
||||||
@@ -308,3 +323,6 @@ private fun cleanedValue(value: String?): String? {
|
|||||||
if (upper == "NONE" || upper == "N/A" || upper == "NA" || upper == "NULL") return null
|
if (upper == "NONE" || upper == "N/A" || upper == "NA" || upper == "NULL") return null
|
||||||
return trimmed
|
return trimmed
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val standardPlateRegex = Regex("^[A-Z]{2}\\d{1,2}[A-Z]{1,3}\\d{3,4}$")
|
||||||
|
private val bhPlateRegex = Regex("^\\d{2}BH\\d{4}[A-Z]{1,2}$")
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ class LlamaClient(
|
|||||||
private val topK: Int
|
private val topK: Int
|
||||||
) {
|
) {
|
||||||
private val systemPrompt =
|
private val systemPrompt =
|
||||||
"Look only at visible text. " +
|
"Read extremely carefully. Look only at visible text. " +
|
||||||
"Return the exact text you can read verbatim. " +
|
"Return the exact text you can read verbatim. " +
|
||||||
"If the text is unclear, partial, or inferred, return NOT CLEARLY VISIBLE. " +
|
"If the text is unclear, partial, or inferred, return NOT CLEARLY VISIBLE. " +
|
||||||
"Do not guess. Do not explain."
|
"Do not guess. Do not explain."
|
||||||
|
|||||||
Reference in New Issue
Block a user