Files
kamidso-back/tests/kamidso/test_context_builder.py
javadandCursor edbaa2acec Add native Didar connectors so chats can query CRM data reliably.
Connector calls, semantic rules, and DuckDB memory keep long runs stable, and stream retry stops chats from stalling.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-12 19:26:47 +03:30

190 lines
6.4 KiB
Python

from kamidso.assistant.context_builder import DEFAULT_BEHAVIOR, KamidsoContextBuilder
from kamidso.contracts.user import CurrentUser
def _user() -> CurrentUser:
return CurrentUser(
id="usr_test",
email="test@example.com",
name="Test",
role="user",
workspace_id="ws_test",
)
def test_default_behavior_identifies_as_kamidso():
assert "Kamidso" in DEFAULT_BEHAVIOR
assert "کامیدسو" in DEFAULT_BEHAVIOR
assert "Never say you are DB-GPT" in DEFAULT_BEHAVIOR
def test_default_behavior_targets_managers_not_chatgpt():
assert "organization, the company" in DEFAULT_BEHAVIOR
assert "managers and decision-makers" in DEFAULT_BEHAVIOR
assert "ChatGPT" in DEFAULT_BEHAVIOR
assert "concise" not in DEFAULT_BEHAVIOR
def test_default_behavior_requires_numeric_precision():
assert "Numeric precision" in DEFAULT_BEHAVIOR
assert "Never compute in your head" in DEFAULT_BEHAVIOR
assert "Never mix units" in DEFAULT_BEHAVIOR
assert "Parts must add up to the total" in DEFAULT_BEHAVIOR
assert "source, filters, Jalali time range" in DEFAULT_BEHAVIOR
assert "numerator and the denominator" in DEFAULT_BEHAVIOR
assert "Count distinct entities" in DEFAULT_BEHAVIOR
assert "Do not present a sample" in DEFAULT_BEHAVIOR
assert "check every number" in DEFAULT_BEHAVIOR
def test_default_behavior_is_thorough_even_without_a_skill():
assert "Even when no skill runs" in DEFAULT_BEHAVIOR
assert "tables of figures" in DEFAULT_BEHAVIOR
assert "mapped" in DEFAULT_BEHAVIOR
assert "hypotheses" in DEFAULT_BEHAVIOR
assert "causes" in DEFAULT_BEHAVIOR
assert "optimal decision options" in DEFAULT_BEHAVIOR
assert "executive summary" not in DEFAULT_BEHAVIOR.lower()
assert "follow that skill's output structure" in DEFAULT_BEHAVIOR
def test_files_without_report_use_full_agent_not_auto_skill():
ctx = KamidsoContextBuilder().build(_user(), files=["file_1"])
assert ctx.skills == []
def test_selected_skill_with_files_is_optional_hint():
ctx = KamidsoContextBuilder().build(
_user(),
skill="root-cause-investigator",
files=["file_1"],
)
assert ctx.skills == ["root-cause-investigator"]
assert "root-cause-investigator" in ctx.behavior
assert "optional hint" in ctx.behavior
assert "MUST be `load_skill`" not in ctx.behavior
assert "Do NOT skip the skill" not in ctx.behavior
def test_files_report_mode_does_not_force_a_skill():
ctx = KamidsoContextBuilder().build(
_user(),
files=["file_1"],
analysis_mode="report",
)
assert ctx.skills == []
def test_files_keep_named_skill_when_explicit():
ctx = KamidsoContextBuilder().build(
_user(),
skill="sales-intelligence",
files=["file_1"],
)
assert ctx.skills == ["sales-intelligence"]
def test_attached_knowledge_is_named_in_behavior():
ctx = KamidsoContextBuilder().build(
_user(),
knowledge=["kb_1"],
ext_info={"knowledge_space_label": "پاسخ فنی واحد معاملات"},
)
assert "پاسخ فنی واحد معاملات" in ctx.behavior
assert "knowledge space is attached" in ctx.behavior
def test_attached_database_is_primary_source():
ctx = KamidsoContextBuilder().build(
_user(),
datasources=["sqlite_Walmart_Sales"],
ext_info={"database_label": "Walmart Sales"},
)
assert ctx.skills == []
assert "database()" in ctx.behavior
assert "code_interpreter" in ctx.behavior
assert "Walmart Sales" in ctx.behavior
assert "Excel/CSV" in ctx.behavior
assert "count" in ctx.behavior.lower()
assert "never pull a large table" in ctx.behavior.lower()
assert "Do not call `sql_query`" in ctx.behavior
def test_explicit_database_skill_is_kept():
ctx = KamidsoContextBuilder().build(
_user(),
skill="sales-intelligence",
datasources=["mongo_ops"],
)
assert ctx.skills == ["sales-intelligence"]
def test_multiple_attached_databases_are_named():
ctx = KamidsoContextBuilder().build(
_user(),
datasources=["ds_1", "ds_2"],
files=["file_1"],
ext_info={"database_labels": ["فروش", "عملیات"]},
)
assert ctx.skills == []
assert "فروش" in ctx.behavior
assert "عملیات" in ctx.behavior
assert "Pass `source=`" in ctx.behavior
assert "code_interpreter" in ctx.behavior
assert "database()" in ctx.behavior
assert "Do not reopen Excel/CSV" not in ctx.behavior
def test_no_attached_source_forbids_leftover_runtime_files():
ctx = KamidsoContextBuilder().build(_user())
assert ctx.skills == []
assert "No file or database is attached this turn" in ctx.behavior
assert "data/runtime" in ctx.behavior
assert "question tool" in ctx.behavior
def test_files_only_forbid_sql_and_database_question():
ctx = KamidsoContextBuilder().build(_user(), files=["file_1"])
assert "File(s) are attached this turn" in ctx.behavior
assert "Do NOT call `sql_query`" in ctx.behavior
assert "Do NOT ask which database" in ctx.behavior
assert "No file or database is attached this turn" not in ctx.behavior
def test_selected_skill_appends_settings_and_rule_pack_instructions():
ctx = KamidsoContextBuilder().build(
_user(),
skill="iran-payroll-compliance",
skill_context="Legal Rule Pack IR-1405 v1.0",
)
assert ctx.skills == ["iran-payroll-compliance"]
assert "optional hint" in ctx.behavior
assert "IR-1405" in ctx.behavior
assert "Article 38" in ctx.behavior
def test_connector_only_does_not_claim_nothing_is_attached():
ctx = KamidsoContextBuilder().build(
_user(),
ext_info={
"connector_ids": ["didar-a"],
"connector_labels": ["دیدار فروش"],
},
)
assert "No file or database is attached this turn" not in ctx.behavior
assert "connector_call" in ctx.behavior
assert "دیدار فروش" in ctx.behavior
assert "validation_error" in ctx.behavior
def test_connector_with_file_keeps_both_sources():
ctx = KamidsoContextBuilder().build(
_user(),
files=["file_1"],
ext_info={"connector_ids": ["didar-a"], "connector_labels": ["دیدار فروش"]},
)
assert "File(s) are attached this turn" in ctx.behavior
assert "connector_call" in ctx.behavior
assert "code_interpreter" in ctx.behavior