Files
inquiry_robot/inquiry-agent/agent/jobs/recognition.py
T

99 lines
3.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
识别任务壳:入队 Redis Stream,Worker HTTP 槽认领后跑占位处理。
本文件职责:识别入队;Worker 槽消费。kind=vision 跑私聊图片波次,kind=attachment 跑附件材料,其它 kind 仍占位。
禁止:回调线程同步等识别完成;禁止本模块写主账六态。
"""
from __future__ import annotations
import logging
from dataclasses import dataclass
from typing import Any, Optional
from agent.redis_coord import get_redis_runtime, try_acquire_idempotency
from agent.redis_coord.runtime import RedisRuntime
from agent.redis_coord.stream_queue import StreamQueue
logger = logging.getLogger(__name__)
@dataclass
class RecognitionEnqueueResult:
accepted: bool
entry_id: str = ""
reason: str = ""
def recognition_stream(redis: Optional[RedisRuntime] = None) -> StreamQueue:
"""返回识别 Stream 句柄。"""
rt = redis or get_redis_runtime()
return rt.recognition_stream
def enqueue_recognition(
*,
kind: str,
payload: dict[str, Any],
idempotency_key: str = "",
redis: Optional[RedisRuntime] = None,
) -> RecognitionEnqueueResult:
"""
识别任务入队(快回)。
kind 例:attachment_text / vision / sheet_map。
"""
rt = redis or get_redis_runtime()
if idempotency_key:
ok = try_acquire_idempotency(
rt.client,
scope="recognition",
idempotency_key=idempotency_key,
ttl_seconds=600,
)
if not ok:
return RecognitionEnqueueResult(accepted=False, reason="duplicate_idempotency_key")
body = {"kind": kind, "payload": payload}
entry_id = rt.recognition_stream.enqueue(
payload=body,
idempotency_key=idempotency_key,
)
logger.info("recognition.enqueue kind=%s id=%s", kind, entry_id)
return RecognitionEnqueueResult(accepted=True, entry_id=entry_id)
def process_recognition(data: dict[str, Any]) -> dict[str, Any]:
"""
Worker 槽:vision 跑图片波次,其它 kind 仍走占位壳。
禁止在本函数写六态。
"""
kind = str(data.get("kind") or "")
payload = data.get("payload") if isinstance(data.get("payload"), dict) else {}
if kind == "vision":
from agent.handlers.image_inquiry import finish_queued_image
return finish_queued_image(payload)
if kind == "attachment":
from agent.handlers.attachment_inquiry import finish_queued_attachment
return finish_queued_attachment(payload)
return process_recognition_stub(data)
def process_recognition_stub(data: dict[str, Any]) -> dict[str, Any]:
"""
识别占位:回显 kind,不读附件、不调模型。
Worker 槽调用;正式实现替换为本函数旁的真实处理器。
"""
kind = str(data.get("kind") or "unknown")
payload = data.get("payload") or {}
logger.info("recognition.stub kind=%s keys=%s", kind, sorted(payload.keys()) if isinstance(payload, dict) else [])
return {
"ok": True,
"stub": True,
"kind": kind,
"note": "识别壳:未跑真实抽取",
}