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
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
DOC_PREVIEW_HOST_ACTION_TOOL as _DOC_PREVIEW_HOST_ACTION_TOOL,
find_document_host_action_tool,
looks_uploaded_document_course_request as _looks_uploaded_doc_course_request,
looks_uploaded_document_lesson_preview_request as _looks_uploaded_doc_lesson_preview_request,
normalize_document_contract_text as _normalize_doc_preview_text,
uploaded_document_attachments_from_state as _uploaded_document_attachments_from_state,
)
Expand Down Expand Up @@ -144,25 +145,7 @@ def _should_request_uploaded_doc_preview(
return False
if not _uploaded_document_attachments_from_state(state):
return False
normalized = _normalize_doc_preview_text(query)
return any(
marker in normalized
for marker in (
"preview",
"xem truoc",
"ban xem truoc",
"ban nhap",
"draft",
"cap nhat bai hoc",
"tao ban xem truoc",
"lesson patch",
"preview_lesson_patch",
"source_references",
"citation",
"trich dan",
"nguon",
)
)
return _looks_uploaded_doc_lesson_preview_request(query)


def _resolve_doc_preview_lesson_id(state: AgentState | None) -> str:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

from app.engine.multi_agent.document_preview_contract import (
has_uploaded_document_context as _has_uploaded_document_context,
looks_uploaded_document_course_request as _looks_uploaded_document_course_request,
looks_uploaded_document_lesson_preview_request as _looks_uploaded_document_lesson_preview_request,
uploaded_document_attachments_from_context as _uploaded_document_attachments,
)
from app.engine.multi_agent.direct_session_memory_runtime import (
Expand Down Expand Up @@ -121,48 +123,11 @@ def _looks_uploaded_document_preview_request(query: str) -> bool:
folded = _fold_direct_text(query)
if not folded:
return False
preview_markers = (
"approval_token",
"ban nhap",
"ban xem truoc",
"citation",
"diff",
"lesson patch",
"preview",
"preview_lesson_patch",
"source references",
"source_references",
"lap bai giang",
"soan bai giang",
"soan giao an",
"tao bai giang",
"tao giao an",
"tao hoc lieu",
"tao ban xem truoc",
"tao khoa hoc",
"thiet ke bai giang",
"thiet ke khoa hoc",
"xay dung bai giang",
"cau truc khoa hoc",
"toan bo khoa",
"cay khoa",
"chia khoa",
"course architect",
"course outline",
"course syllabus",
"curriculum",
"de cuong khoa",
"de cuong mon",
"giao trinh",
"ke hoach giang day",
"learning path",
"lo trinh hoc",
"syllabus",
"generate_course_from_document",
"trich dan",
"xem truoc",
return _looks_uploaded_document_course_request(
folded
) or _looks_uploaded_document_lesson_preview_request(
folded
)
return any(marker in folded for marker in preview_markers)


def _looks_uploaded_context_fact_query(query: str, ctx: dict[str, Any]) -> bool:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,45 @@
"outline",
)

_LESSON_AUTHORING_EXCLUSION_MARKERS = (
"bai tap",
"bai kiem tra",
"cau hoi",
"kiem tra",
"quiz",
)

_LESSON_AUTHORING_VERBS = (
"build",
"create",
"lam",
"lap",
"soan",
"tao",
"thiet ke",
"viet",
"write",
"xay dung",
)

_LESSON_PREVIEW_REQUEST_MARKERS = (
"approval_token",
"ban nhap",
"ban xem truoc",
"cap nhat bai hoc",
"citation",
"diff",
"draft",
"lesson patch",
"preview",
"preview_lesson_patch",
"source references",
"source_references",
"tao ban xem truoc",
"trich dan",
"xem truoc",
)
Comment thread
coderabbitai[bot] marked this conversation as resolved.


def normalize_document_contract_text(value: Any) -> str:
text = str(value or "").replace("\\_", "_")
Expand Down Expand Up @@ -127,6 +166,23 @@ def looks_uploaded_document_course_request(query: str) -> bool:
return any(marker in normalized for marker in _COURSE_REQUEST_MARKERS)


def _looks_singular_lesson_authoring_request(normalized: str) -> bool:
if not ("bai hoc" in normalized or "lesson" in normalized):
return False
if any(marker in normalized for marker in _LESSON_AUTHORING_EXCLUSION_MARKERS):
return False
return any(marker in normalized for marker in _LESSON_AUTHORING_VERBS)


def looks_uploaded_document_lesson_preview_request(query: str) -> bool:
normalized = normalize_document_contract_text(query)
if not normalized:
return False
return any(marker in normalized for marker in _LESSON_PREVIEW_REQUEST_MARKERS) or (
_looks_singular_lesson_authoring_request(normalized)
)


def _runtime_tool_name(
tool: Any,
*,
Expand Down
119 changes: 18 additions & 101 deletions maritime-ai-service/app/engine/multi_agent/tool_collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,12 @@
from typing import Any, Optional

from app.core.config import settings
from app.engine.multi_agent.document_preview_contract import (
looks_uploaded_document_course_request as _contract_looks_uploaded_document_course_request,
looks_uploaded_document_lesson_preview_request as _contract_looks_uploaded_document_lesson_preview_request,
)
from app.engine.multi_agent.state import AgentState

logger = logging.getLogger(__name__)


Expand All @@ -24,6 +29,14 @@ def _normalize_for_intent(query: str) -> str:
return _load_attr("app.engine.multi_agent.direct_intent", "_normalize_for_intent")(query)


def _looks_uploaded_document_course_request(query: str) -> bool:
return _contract_looks_uploaded_document_course_request(query)


def _looks_uploaded_document_lesson_preview_request(query: str) -> bool:
return _contract_looks_uploaded_document_lesson_preview_request(query)


def _needs_web_search(query: str) -> bool:
return _load_attr("app.engine.multi_agent.direct_intent", "_needs_web_search")(query)

Expand Down Expand Up @@ -277,113 +290,17 @@ def _has_uploaded_document_context_state(state: Optional[AgentState]) -> bool:
def _looks_like_document_preview_request(query: str, state: Optional[AgentState]) -> bool:
if not _has_uploaded_document_context_state(state):
return False
normalized = _normalize_for_intent(query)
return any(
marker in normalized
for marker in (
"preview",
"xem truoc",
"ban xem truoc",
"ban nhap",
"draft",
"cap nhat bai hoc",
"lap bai giang",
"soan bai giang",
"soan giao an",
"tao bai giang",
"tao giao an",
"tao hoc lieu",
"tao bai hoc",
"tao khoa hoc",
"thiet ke bai giang",
"thiet ke khoa hoc",
"xay dung bai giang",
"cau truc khoa hoc",
"toan bo khoa",
"cay khoa",
"chia khoa",
"course architect",
"course outline",
"course syllabus",
"curriculum",
"de cuong khoa",
"de cuong mon",
"giao trinh",
"ke hoach giang day",
"learning path",
"lo trinh hoc",
"syllabus",
"generate_course_from_document",
"lesson patch",
"preview_lesson_patch",
"source_references",
"citation",
"trich dan",
"nguon",
)
return _looks_uploaded_document_course_request(
query
) or _looks_uploaded_document_lesson_preview_request(
query
)


def _looks_like_document_course_preview_request(query: str, state: Optional[AgentState]) -> bool:
if not _has_uploaded_document_context_state(state):
return False
normalized = _normalize_for_intent(query)
if any(
marker in normalized
for marker in (
"preview_lesson_patch",
"lesson patch",
"bai hoc hien tai",
"cap nhat bai hoc",
)
):
return False
return any(
marker in normalized
for marker in (
"generate_course_from_document",
"lap bai giang",
"soan bai giang",
"soan giao an",
"tao bai giang",
"tao giao an",
"tao hoc lieu",
"course architect",
"course outline",
"course syllabus",
"curriculum",
"full course",
"toan bo khoa",
"cay khoa",
"chia khoa",
"chia thanh bai",
"chia thanh chuong",
"chuong trinh dao tao",
"de cuong khoa",
"de cuong mon",
"giao trinh",
"ke hoach giang day",
"khoa dao tao",
"khoa day du",
"khoa hoan chinh",
"learning path",
"lo trinh hoc",
"lo trinh khoa",
"nhieu bai hoc",
"nhieu chuong",
"phan chia bai hoc",
"syllabus",
"tao khoa hoc",
"thiet ke bai giang",
"thiet ke khoa hoc",
"xay dung bai giang",
"cau truc khoa hoc",
"chuong/bai",
"chuong bai",
"module",
"outline",
)
)
return _looks_uploaded_document_course_request(query)


def _document_preview_host_action_tools(tools: list[Any]) -> list[Any]:
Expand Down
27 changes: 27 additions & 0 deletions maritime-ai-service/tests/unit/test_document_context_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -507,6 +507,33 @@ def test_uploaded_document_preview_request_bypasses_fact_fast_path():
assert not _looks_uploaded_context_fact_query(query, ctx)


def test_uploaded_document_lesson_creation_request_bypasses_fact_fast_path():
from app.engine.multi_agent.direct_node_uploaded_context import (
_looks_uploaded_context_fact_query,
_looks_uploaded_document_preview_request,
)

ctx = {
"document_context": {
"attachments": [
{
"file_name": "lesson.docx",
"media_kind": "document",
"parser": "markitdown",
"markdown": (
"Ke hoach bai hoc thu nghiem Wiii\n"
"Chu de: An toan hang hai va approval_token.\n"
),
}
]
}
}
query = "tao cho minh bai hoc"

assert _looks_uploaded_document_preview_request(query)
assert not _looks_uploaded_context_fact_query(query, ctx)


def test_uploaded_document_visual_guard_does_not_describe_frames_without_vision():
from app.engine.multi_agent.direct_node_uploaded_context import (
_build_uploaded_document_visual_guard_answer,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
has_document_preview_host_action_tool,
has_uploaded_document_context,
looks_uploaded_document_course_request,
looks_uploaded_document_lesson_preview_request,
uploaded_document_attachments_from_context,
uploaded_document_attachments_from_state,
)
Expand Down Expand Up @@ -44,6 +45,13 @@ def test_uploaded_document_course_intent_is_shared_by_preview_and_tool_rounds():
assert not looks_uploaded_document_course_request("cap nhat bai hoc hien tai")


def test_uploaded_document_lesson_preview_intent_is_shared_by_preview_and_tool_rounds():
assert looks_uploaded_document_lesson_preview_request("tao cho minh bai hoc")
assert looks_uploaded_document_lesson_preview_request("cap nhat bai hoc hien tai")
assert looks_uploaded_document_lesson_preview_request("create a lesson from this file")
assert not looks_uploaded_document_lesson_preview_request("tao cau hoi cho bai hoc")


def test_document_preview_forced_tool_choice_prefers_course_when_available():
tools = [
SimpleNamespace(name=DOC_PREVIEW_HOST_ACTION_TOOL),
Expand All @@ -59,6 +67,10 @@ def test_document_preview_forced_tool_choice_prefers_course_when_available():
document_preview_forced_tool_choice("cap nhat bai hoc hien tai", tools)
== DOC_PREVIEW_HOST_ACTION_TOOL
)
assert (
document_preview_forced_tool_choice("tao cho minh bai hoc", tools)
== DOC_PREVIEW_HOST_ACTION_TOOL
)


def test_extract_document_preview_capabilities_from_state_and_context():
Expand Down
Loading