diff --git a/changai/changai/api/v2/auto_gen_api.py b/changai/changai/api/v2/auto_gen_api.py index 8fcf451..1c931dd 100644 --- a/changai/changai/api/v2/auto_gen_api.py +++ b/changai/changai/api/v2/auto_gen_api.py @@ -201,11 +201,11 @@ def _extract_existing_keys(data: List[Any]) -> Set[tuple]: return keys -def _build_master_data_row(entity_type: str, entity_id:str,title_field:str) -> Dict[str, Any]: +def _build_master_data_row(entity_type: str, entity_id:str,title_field:str,filter: Optional[Dict[str, Any]]) -> Dict[str, Any]: return { "entity_type": entity_type, - "entity_id": title_field, - "filters": {"field": title_field if title_field else "name", "value": entity_id}, + "entity_id": entity_id, + "filters": filter or {"field": title_field if title_field else "name", "value": entity_id}, } @@ -271,25 +271,17 @@ def sync_master_data_smart() -> Dict[str, Any]: for rec in live_records: if mod == "Item": item_code = rec.get("name") - if item_code: - rebuilt_rows.append( - _build_master_data_row( - entity_type, - item_code, - "name" - )) item_name = rec.get(title_field) - if item_name: + if item_code: + filters = [{"field": "item_code", "value": item_code}] + if item_name and item_name != item_code: + filters.append({"field": "item_name", "value": item_name}) rebuilt_rows.append( - _build_master_data_row( - entity_type, - item_name, - title_field - ) - ) - else: + _build_master_data_row(entity_type, item_code, title_field, filters) + ) + else: entity_id = rec.get(title_field) if title_field in rec else rec.get("name") - rebuilt_rows.append(_build_master_data_row(entity_type, entity_id,title_field)) + rebuilt_rows.append(_build_master_data_row(entity_type, entity_id, title_field, None)) final_data = rebuilt_rows meta["last_sync"] = str(now_datetime()) settings = frappe.get_single("ChangAI Settings") @@ -463,6 +455,7 @@ def _update_or_create_table_block( "table": table, "description": "", "fields": fields, + "grain":"", "desc_done": False, } def _build_field_entry( @@ -559,6 +552,12 @@ def _has_pending_descriptions(fields: List[Dict[str, Any]]) -> bool: if isinstance(field, dict) and field.get("name") ) +def _infer_grain_label(meta_dt: Any, table: str) -> str: + + if meta_dt.istable: + return f"GRAIN: 1 row per parent document + idx (child table of {table}). Comparison-ready across parent records." + return f"GRAIN: 1 row per {_strip_tab(table)} document (master/transaction). Use only for single-entity lookups, not cross-record comparison unless fields are per-relationship (e.g. supplier, price_list)." + def _process_schema_table(table: str, by_table: Dict[str, Dict[str, Any]]) -> bool: dt = _strip_tab(table) @@ -569,6 +568,7 @@ def _process_schema_table(table: str, by_table: Dict[str, Dict[str, Any]]) -> bo meta_dt = frappe.get_meta(dt) block = by_table.setdefault(table, {}) block["is_table"] = bool(meta_dt.istable) + block["grain"] = _infer_grain_label(meta_dt, table) existing_fields = _get_existing_fields_for_table(by_table, table) fields = _build_fields_from_meta(meta_dt, existing_fields) _update_or_create_table_block(by_table, table, fields) @@ -655,7 +655,6 @@ def fill_missing_field_descriptions( def sync_tables_and_schema_smart() -> Dict[str, Any]: payload = _read_filedoctype(SCHEMA_YAML, RAG_FOLDER) meta, tables_blocks = _normalize_schema_payload(payload) - by_table = _build_table_map(tables_blocks) last_sync_raw = meta.get("last_sync") changed_doctypes = _get_changed_doctypes(last_sync_raw) diff --git a/changai/changai/api/v2/build_cards_faiss_index_v2.py b/changai/changai/api/v2/build_cards_faiss_index_v2.py index 79105e9..2841cb8 100644 --- a/changai/changai/api/v2/build_cards_faiss_index_v2.py +++ b/changai/changai/api/v2/build_cards_faiss_index_v2.py @@ -162,29 +162,12 @@ def _is_valid_schema_table(table_block: Any) -> bool: return isinstance(table_block, dict) and "table" in table_block -def _build_field_metadata(table_name: str, field_name: str, module: str, join_hint: str, options: Any) -> Dict[str, Any]: - metadata = { - "type": "field", - "table": table_name, - "field": field_name, - "module": module, - } - if options: - metadata["options"] = options - if join_hint: - metadata["join_hint"] = join_hint - return metadata - - -def _build_field_page_content(table_name: str, field_name: str, field_desc: str, join_hint: str, options: Any) -> str: - page_content = f"[FIELD] {field_name} | [TABLE] {table_name}\n{field_desc}" - if join_hint: - page_content += f"\n{join_hint}" - if options: - page_content += f"\n{options}" - return page_content - -def _build_field_document(table_name: str, module: str, field_row: Dict[str, Any]) -> Optional[Document]: +def _build_field_document( + table_name: str, + module: str, + field_row: Dict[str, Any], + grain: str = "" # ✅ Add this param +) -> Optional[Document]: if not isinstance(field_row, dict): return None @@ -194,37 +177,41 @@ def _build_field_document(table_name: str, module: str, field_row: Dict[str, Any field_desc = field_row.get("description", "") or "" join_hint = field_row.get("join_hint") or "" - child_hint = field_row.get("child_hint") or "" # ✅ Add this + child_hint = field_row.get("child_hint") or "" options = field_row.get("options") or "" - fieldtype = field_row.get("fieldtype") or "" # ✅ Add this - is_table_field = fieldtype in ("Table", "Table MultiSelect") # ✅ Add this + fieldtype = field_row.get("fieldtype") or "" + is_table_field = fieldtype in ("Table", "Table MultiSelect") # Build page content page_content = f"[FIELD] {field_name} | [TABLE] {table_name}\n{field_desc}" if join_hint: page_content += f"\n{join_hint}" - if child_hint and is_table_field: # ✅ Add child hint to content + if child_hint and is_table_field: if isinstance(child_hint, dict): page_content += f"\nChild Table: {child_hint.get('child_table', '')}" else: page_content += f"\n{child_hint}" if options: page_content += f"\n{options}" + if grain: # ✅ Add this + page_content += f"\nGRAIN: {grain}" # ✅ Add this # Build metadata metadata = { "type": "field", "table": table_name, "field": field_name, - "fieldtype": fieldtype, # ✅ Store fieldtype + "fieldtype": fieldtype, "module": module, } if options: metadata["options"] = options if join_hint: metadata["join_hint"] = join_hint - if child_hint and is_table_field: # ✅ Store child_hint + if child_hint and is_table_field: metadata["child_hint"] = child_hint + if grain: # ✅ Add this + metadata["grain"] = grain # ✅ Add this — this is what retrieve.py reads return Document( page_content=page_content, @@ -267,6 +254,7 @@ def build_schema_docs(schema: Dict[str, Any]) -> List[Document]: table_name = table_block.get("table") module = table_block.get("module", "") + grain = table_block.get("grain", "") fields = table_block.get("fields") or [] if not isinstance(fields, list): @@ -277,7 +265,7 @@ def build_schema_docs(schema: Dict[str, Any]) -> List[Document]: if field_name in GENERIC_FIELDS: continue - doc = _build_field_document(table_name, module, field_row) + doc = _build_field_document(table_name, module, field_row,grain) if doc: docs.append(doc) @@ -307,13 +295,24 @@ def _build_entity_text(md: Dict[str, Any]) -> str: def _build_entity_metadata(md: Dict[str, Any]) -> Dict[str, Any]: + filters = md.get("filters") + if isinstance(filters, dict): + filters = [filters] + elif not isinstance(filters, list): + filters = [] + + labels = [ + f"{f.get('field')}:{f.get('value')}" + for f in filters + if isinstance(f, dict) and f.get("field") + ] + entity_label = "; ".join(labels) if labels else "" + return { "type": "entity", "entity_type": md.get("entity_type"), "entity_id": md.get('entity_id'), - "entity_label": f"{md.get('filters', {}).get('field')}:{md.get('filters', {}).get('value')}" - # "canonical_name": md.get("canonical_name"), - # "aliases": md.get("aliases", []), + "entity_label": entity_label, } @@ -458,7 +457,7 @@ def build_schema_fvs_job(): # schema = clean_schema(schema,schema_path) schema_docs = build_schema_docs(schema) app_base, _, _, schema_path, _,schema_emb_dir, _ = _get_fvs_paths() - _build_and_save_faiss(schema_docs, schema_path, "ERPNext Schema FVS", app_base) + # _build_and_save_faiss(schema_docs, schema_path, "ERPNext Schema FVS", app_base) save_field_matrix(schema_docs, schema_emb_dir) frappe.logger().info(f"ERPNext Schema FVS built: {len(schema_docs)} docs") except Exception : diff --git a/changai/changai/api/v2/fvs_stores/erpnext/emb_dir/field_docs.pkl b/changai/changai/api/v2/fvs_stores/erpnext/emb_dir/field_docs.pkl index bcbf024..2650d8b 100644 Binary files a/changai/changai/api/v2/fvs_stores/erpnext/emb_dir/field_docs.pkl and b/changai/changai/api/v2/fvs_stores/erpnext/emb_dir/field_docs.pkl differ diff --git a/changai/changai/api/v2/fvs_stores/erpnext/emb_dir/field_embs.npy b/changai/changai/api/v2/fvs_stores/erpnext/emb_dir/field_embs.npy index e9fa2e0..28aa17e 100644 Binary files a/changai/changai/api/v2/fvs_stores/erpnext/emb_dir/field_embs.npy and b/changai/changai/api/v2/fvs_stores/erpnext/emb_dir/field_embs.npy differ diff --git a/changai/changai/api/v2/fvs_stores/erpnext/report_fvs/index.faiss b/changai/changai/api/v2/fvs_stores/erpnext/report_fvs/index.faiss index fcf36c1..4921997 100644 Binary files a/changai/changai/api/v2/fvs_stores/erpnext/report_fvs/index.faiss and b/changai/changai/api/v2/fvs_stores/erpnext/report_fvs/index.faiss differ diff --git a/changai/changai/api/v2/fvs_stores/erpnext/report_fvs/index.pkl b/changai/changai/api/v2/fvs_stores/erpnext/report_fvs/index.pkl index 83e458c..c01dabe 100644 Binary files a/changai/changai/api/v2/fvs_stores/erpnext/report_fvs/index.pkl and b/changai/changai/api/v2/fvs_stores/erpnext/report_fvs/index.pkl differ diff --git a/changai/changai/api/v2/fvs_stores/erpnext/table_fvs/index.faiss b/changai/changai/api/v2/fvs_stores/erpnext/table_fvs/index.faiss index 171a742..491dec9 100644 Binary files a/changai/changai/api/v2/fvs_stores/erpnext/table_fvs/index.faiss and b/changai/changai/api/v2/fvs_stores/erpnext/table_fvs/index.faiss differ diff --git a/changai/changai/api/v2/fvs_stores/erpnext/table_fvs/index.pkl b/changai/changai/api/v2/fvs_stores/erpnext/table_fvs/index.pkl index 7f2d9a1..7cc13aa 100644 Binary files a/changai/changai/api/v2/fvs_stores/erpnext/table_fvs/index.pkl and b/changai/changai/api/v2/fvs_stores/erpnext/table_fvs/index.pkl differ diff --git a/changai/changai/api/v2/retrieve.py b/changai/changai/api/v2/retrieve.py index 5e02e85..9779376 100644 --- a/changai/changai/api/v2/retrieve.py +++ b/changai/changai/api/v2/retrieve.py @@ -518,6 +518,7 @@ def call_fvs_field_search_global_k( is_table = meta.get("is_table") table = meta.get("table") field = meta.get("field") or meta.get("name") + grain = meta.get("grain", "") if not table or not field: continue @@ -562,6 +563,7 @@ def call_fvs_field_search_global_k( grouped.setdefault(table, { "is_table": is_table, + "grain":grain, "fields": [] }) grouped[table]["fields"].append(name) diff --git a/changai/changai/api/v2/schema_utils.py b/changai/changai/api/v2/schema_utils.py index 3f52633..ac1a385 100644 --- a/changai/changai/api/v2/schema_utils.py +++ b/changai/changai/api/v2/schema_utils.py @@ -30,6 +30,8 @@ JSON_EXT = ".json" YAML_EXT = ".yaml" + + def get_report_filter_fields(report_name: str): try: script = get_script(report_name).get("script") or "" @@ -61,12 +63,24 @@ def phonetic_bucket(): master_items = master_data_content["data"] for item in master_items: table = item["entity_type"] - field = item["filters"]["field"] - value = item["filters"]["value"] - _VALUE_TO_FIELD[value] = f"{table}.{field}:{value}" - first_word = value.split()[0] - key = jellyfish.metaphone(first_word) - _PHONETIC_BUCKETS[key].append(value) + filters = item.get("filters") + if isinstance(filters, dict): + filters = [filters] + elif not isinstance(filters, list): + continue + + for f in filters: + if not isinstance(f, dict): + continue + field = f.get("field") + value = f.get("value") + if not field or not value: + continue + + _VALUE_TO_FIELD[value] = f"{table}.{field}:{value}" + first_word = value.split()[0] + key = jellyfish.metaphone(first_word) + _PHONETIC_BUCKETS[key].append(value) @frappe.whitelist(allow_guest=False) @@ -210,18 +224,31 @@ def is_doctype_schema_changed(doc, last_sync): latest = max(candidates, default=None) return bool(latest and last_sync and latest > get_datetime(last_sync)) -def is_master_data_changed(last_sync, stored_data: list): +def is_master_data_changed(last_sync: str, stored_data: list): for doc in MASTER_DOCTYPES: meta = frappe.get_meta(doc) title_field = meta.title_field or "name" entity_type = f"tab{doc}" - - # ✅ Only compare rows matching title_field allowed_fields = [f.fieldname for f in meta.fields] + ["name"] if title_field not in allowed_fields: frappe.log_error(f"Invalid title_field: {title_field}", "is_master_data_changed") continue - + stored_titles = set() + for row in stored_data: + if (row.get("entity_type") != entity_type): + continue + filters = row.get("filters") + if isinstance(filters, dict): + filters = [filters] + elif not isinstance(filters, list): + filters = [] + for f in filters: + if ( + isinstance(f, dict) + and f.get("field") == title_field + and f.get("value") + ): + stored_titles.add(f.get("value")) live_records = frappe.get_all( doc, fields=[title_field], @@ -231,13 +258,13 @@ def is_master_data_changed(last_sync, stored_data: list): for rec in live_records: if rec.get(title_field): live_titles.add(rec.get(title_field)) - + if stored_titles == live_titles: + return False if stored_titles != live_titles: return True - return False -@frappe.whitelist(allow_guest=False) + def check_file_updates(file_name: str): RAG_FOLDER = "Home/RAG Sources" from changai.changai.api.v2.build_cards_faiss_index_v2 import _read_file_doc @@ -279,7 +306,6 @@ def check_file_updates(file_name: str): stored_data = parsed.get("data", []) if isinstance(parsed, dict) else [] else: stored_data = [] - if is_master_data_changed(last_sync, stored_data): changed = True @@ -421,6 +447,7 @@ def format_schema_context(grouped: dict) -> str: if isinstance(table_data, dict): raw_fields = table_data.get("fields", []) is_table_value = table_data.get("is_table") + grain = table_data.get("grain", "") if is_table_value is None: child = is_child_table(table) @@ -429,11 +456,14 @@ def format_schema_context(grouped: dict) -> str: else: raw_fields = table_data child = is_child_table(table) + grain = "" fields = enrich_fields_for_sql_context(table, raw_fields) parts.append(f"TABLE: {table}") parts.append(f"TYPE: {'Child Table' if child else 'Main Table'}") + if grain: + parts.append(f"GRAIN: {grain}") if child: parts.append("JOIN RULES:") diff --git a/changai/changai/api/v2/text2sql_pipeline_v2.py b/changai/changai/api/v2/text2sql_pipeline_v2.py index 43941e3..976dfa7 100644 --- a/changai/changai/api/v2/text2sql_pipeline_v2.py +++ b/changai/changai/api/v2/text2sql_pipeline_v2.py @@ -443,6 +443,9 @@ def rewrite_question(state: SQLState) -> SQLState: return {**state, "error": str(e)} +import frappe +from typing import Dict, Any + ENTITY_CREATION_PROMPT = read_asset("create_entity_prompt.txt", base="prompts") def create_entity(state:SQLState): request_id = state.get("request_id") @@ -1188,28 +1191,19 @@ def run_text2sql_pipeline( request_id: str, sendNonErptoAI: bool = False ) -> Dict: - memory_status = check_memory_status() - - # -------------------------------------------------- - # CACHE - # -------------------------------------------------- logs = find_similar_log_question(user_question) - if logs.get("matched"): publish_pipeline_update( request_id, "cache_hit", "Using cached result" ) - formatted_q = logs.get("rewritten_question") sql = logs.get("sql") - tables = json.loads(logs.get("tables") or "[]") fields = logs.get("fields") or "" entity_debug = json.loads(logs.get("entity_debug") or "{}") - return _handle_sql_result( memory_status, request_id, @@ -1489,4 +1483,4 @@ def guardrail_router_test( "question": question, "query_type": "NON_ERP", "error": str(e) - } \ No newline at end of file + } diff --git a/changai/changai/doctype/changai_settings/changai_settings.js b/changai/changai/doctype/changai_settings/changai_settings.js index 81a31a6..5549758 100644 --- a/changai/changai/doctype/changai_settings/changai_settings.js +++ b/changai/changai/doctype/changai_settings/changai_settings.js @@ -108,10 +108,6 @@ frappe.ui.form.on("ChangAI Settings", { fieldname: "gemini_project_id", text: `Google Cloud Project ID for Gemini Paid Tier.`, }, - { - fieldname: "gemini_json_content", - text: `Google Cloud Service Account JSON credentials.`, - }, { fieldname: "llm", text: `Select the AI model used for SQL generation and responses.`, diff --git a/changai/changai/doctype/changai_settings/changai_settings.json b/changai/changai/doctype/changai_settings/changai_settings.json index e1af778..8e42a39 100644 --- a/changai/changai/doctype/changai_settings/changai_settings.json +++ b/changai/changai/doctype/changai_settings/changai_settings.json @@ -285,7 +285,8 @@ { "fieldname": "gemini_json_content", "fieldtype": "Code", - "label": "Service Account Credentials" + "label": "Service Account Credentials", + "options": "JSON" }, { "fieldname": "gemini_api_key", @@ -407,7 +408,7 @@ "index_web_pages_for_search": 1, "issingle": 1, "links": [], - "modified": "2026-06-15 07:18:36.158706", + "modified": "2026-06-24 13:36:59.025672", "modified_by": "Administrator", "module": "Changai", "name": "ChangAI Settings", diff --git a/changai/changai/prompts/sql_rewrite_sys_prompt.txt b/changai/changai/prompts/sql_rewrite_sys_prompt.txt index 94d0951..b978b7a 100644 --- a/changai/changai/prompts/sql_rewrite_sys_prompt.txt +++ b/changai/changai/prompts/sql_rewrite_sys_prompt.txt @@ -43,18 +43,15 @@ if contains_values = TRUE: - if none, return empty list [] EXAMPLES: "sales for Amrin and Susan" → ["Amrin", "Susan"] -"stock of ITEM-0001 and iPhone" → ["ITEM-0001", "iPhone"] +"stock of ITEM-0001 and iPhone" → ["ITEM-0001", "iPhone","Bag"...etc] "show all customers" → contains_values: false, entity_word: [] TASK 3 — ERP CONTEXTUAL REWRITE - 1. Normalize: - Fix typos, clear English - Do NOT change entity values - 2. Complete intent: - Never change the question's intent — only fix grammar and map ERP terms. - 3. ERP mapping: - Map generic terms to standard ERPNext concepts based on intent - Avoid vague words if clearer business terms exist @@ -114,7 +111,8 @@ STRICT RULES: - Preserve ERPNext business semantics during rewriting and avoid converting ERPNext document lifecycle terms into generic workflow or approval terminology that may change the original meaning. - Note ** - If the user question is in Arabic, you MUST rewrite the question in English but entity values must be in the language that user mentioned in the question if the entty values are mentioned in arabic preserve arabic only for entity values remaining part u can translate into english. - Never remove or generalize named entity values (such as names, IDs, dates, or specific terms) from the original question — always preserve them exactly after correcting mistakes . - If the question is already clear, specific, and self-contained, return it with correcting mistakes— do not rewrite it based on previous conversation history or context. +- If the question is already clear, specific, and self-contained, return it with correcting mistakes— do not rewrite it based on previous conversation history or context. +- Always extract entity words for all proper nouns, named brands, item groups, manufacturers, companies, suppliers, customers, warehouses, territories, and other named business entities, even when they are used as adjectives modifying another noun. Example: Input: اعرض تقرير سجل المخزون للصنف شاشة سامسونج diff --git a/changai/changai/prompts/sql_system_prompt.txt b/changai/changai/prompts/sql_system_prompt.txt index c07920b..ab37502 100644 --- a/changai/changai/prompts/sql_system_prompt.txt +++ b/changai/changai/prompts/sql_system_prompt.txt @@ -17,7 +17,6 @@ BEFORE writing any field or table name, locate it physically in SCHEMA CONTEXT. - Never assume fields. Only use the fields and tables that exist in SCHEMA CONTEXT. - SELECT * is forbidden. Always use explicit fields. - NEVER return empty sql. Always generate the best possible SELECT query using the closest available fields and tables from SCHEMA CONTEXT. - ═══ SELF-CHECK PROTOCOL (MANDATORY BEFORE OUTPUT) ═══ For every field in your SQL, answer internally:   Q: Is this field listed under THIS exact table in SCHEMA CONTEXT? @@ -111,6 +110,10 @@ If you are about to write a forbidden token → STOP → rewrite using MariaDB e   and logic matches the original question exactly. - Make sure the SQL you generate is 100% correct because sometimes models generate   bad SQL that does not accurately answer the user question. +- CRITICAL ITEM FILTER RULE: + If `item_code` or `item_name` exists in SCHEMA CONTEXT, NEVER filter by `item_description` to identify an item. + `item_description` may ONLY be used when the user's intent explicitly refers to the item's description. + LAW 1: sql is NEVER empty. Ever. LAW 2: Every field must exist in SCHEMA CONTEXT under the exact table used. LAW 3: No JOINs unless a link field (→) exists in SCHEMA CONTEXT. @@ -124,10 +127,16 @@ Never ever give empty sql.that is wrong.also donot give syntax errors in sql. also do not assume fields or tables if they are not in the given schema. also Apply docstatus = 1 only for submitted transactional ERP documents such as Sales Invoice, Purchase Invoice, Sales Order, Purchase Order, Payment Entry, Journal Entry, Delivery Note, Purchase Receipt, Stock Entry, Work Order, and similar transaction records. Do NOT apply docstatus filters to master data documents such as Customer, Supplier, Item, Employee, Warehouse, Project, Lead, Opportunity, Address, Contact, Company, Territory, Country, Currency, UOM, Cost Center, Department, and other master records unless the user explicitly asks for Draft, Submitted, or Cancelled records. +Before picking a field, check what it actually represents, not just its name — flags/booleans (e.g. buying, selling, enabled) are never prices or quantities, and a single default/static reference field on a master table (e.g. tabItem.supplier) is not valid for comparing or ranking across multiple suppliers/records. Always prefer the table that stores one row per comparison unit (e.g. per supplier, per price list, per transaction) when the question asks for cheapest/highest/lowest/comparison, even if a same-named field exists elsewhere in the schema. +If a table in SCHEMA CONTEXT includes a GRAIN line, it describes what one row of that table represents. +Use it to decide whether a table can answer the question directly: a table whose GRAIN is +"1 row per document" cannot be used to compare or rank across suppliers, prices, or other +sub-entities — pick a table whose GRAIN shows one row per the specific comparison unit +(e.g. per supplier, per price list, per line item) instead. +a superlative word ("best," "cheapest," "fastest") that has no clear numeric field to sort by should trigger the model to either (a) find the correct underlying numeric field via a join, or (b) explicitly state the ambiguity — not silently drop the ranking and return an unfiltered list - Output Format: { -  "sql": "", -  "orm": "" +  "sql": "" } FINAL CHECK: Did you verify every field exists in SCHEMA CONTEXT? Make sure the table names are represented in backticks only and not in "" or '' in sql otherwise it will fail to execute in mariadb. diff --git a/changai/changai/prompts/test.txt b/changai/changai/prompts/test.txt index 97c080c..d85e25d 100644 --- a/changai/changai/prompts/test.txt +++ b/changai/changai/prompts/test.txt @@ -1,4 +1,4 @@ -You are a STRICT SQL generation assistant for MARIADB +You are a STRICT SQL generation assistant for MariaDB TASK Generate EXACTLY ONE valid, minimal, and executable SQL SELECT query. @@ -10,10 +10,10 @@ RULES - Select only the minimal fields needed (include identifying fields like "name" when relevant). 3. Use JOINs only if explicitly listed and logically required. 4. When joining a child table with its parent, strictly use the child's `parent` field and the parent's `name` field. - 👉 Example: `ON tabSales Invoice Item.parent = tabSales Invoice.name` + - Example: `ON tabSales Invoice Item.parent = tabSales Invoice.name` 5. Always start with SELECT and end with a semicolon. 6. Do not output anything except the SQL query. - ❌ No reasoning, no markdown, no extra text. + - No reasoning, no markdown, no extra text. 7. Format properly: - SQL keywords in uppercase (SELECT, FROM, WHERE, JOIN, ON, GROUP BY, ORDER BY, LIMIT) - Use line breaks between clauses @@ -52,6 +52,6 @@ FINAL OUTPUT (MANDATORY FORMAT) - Do NOT add any explanation, reasoning, or commentary. - Do NOT include markdown (```), phrases like "The final answer is:", or any extra text. - Output must begin directly with SELECT and end with a single semicolon (;). -- output only sql that will execute in MAriaDB no reasoning.no explanation. +- Output only SQL that will execute in MariaDB. No reasoning. No explanation. If you produce anything besides exactly one SQL statement, it will be considered invalid. diff --git a/changai/changai/replicate_model_files/changai_retriever/.cog/openapi_schema.json b/changai/changai/replicate_model_files/changai_retriever/.cog/openapi_schema.json index fc440c1..835d76d 100644 --- a/changai/changai/replicate_model_files/changai_retriever/.cog/openapi_schema.json +++ b/changai/changai/replicate_model_files/changai_retriever/.cog/openapi_schema.json @@ -1 +1,319 @@ -{"components":{"schemas":{"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"title":"Detail","type":"array"}},"title":"HTTPValidationError","type":"object"},"Input":{"properties":{"k":{"default":15,"description":"Top-K results","title":"K","type":"integer"},"user_input":{"description":"Query text","title":"User Input","type":"string"}},"required":["user_input"],"title":"Input","type":"object"},"Output":{"items":{"additionalProperties":true,"type":"object"},"title":"Output","type":"array"},"PredictionRequest":{"properties":{"context":{"additionalProperties":{"type":"string"},"nullable":true,"title":"Context","type":"object"},"created_at":{"format":"date-time","nullable":true,"title":"Created At","type":"string"},"id":{"nullable":true,"title":"Id","type":"string"},"input":{"$ref":"#/components/schemas/Input","nullable":true},"output_file_prefix":{"nullable":true,"title":"Output File Prefix","type":"string"},"webhook":{"format":"uri","maxLength":65536,"minLength":1,"nullable":true,"title":"Webhook","type":"string"},"webhook_events_filter":{"default":["start","output","logs","completed"],"items":{"$ref":"#/components/schemas/WebhookEvent"},"nullable":true,"type":"array"}},"title":"PredictionRequest","type":"object"},"PredictionResponse":{"properties":{"completed_at":{"format":"date-time","nullable":true,"title":"Completed At","type":"string"},"created_at":{"format":"date-time","nullable":true,"title":"Created At","type":"string"},"error":{"nullable":true,"title":"Error","type":"string"},"id":{"nullable":true,"title":"Id","type":"string"},"input":{"$ref":"#/components/schemas/Input","nullable":true},"logs":{"default":"","title":"Logs","type":"string"},"metrics":{"additionalProperties":true,"nullable":true,"title":"Metrics","type":"object"},"output":{"$ref":"#/components/schemas/Output"},"started_at":{"format":"date-time","nullable":true,"title":"Started At","type":"string"},"status":{"$ref":"#/components/schemas/Status","nullable":true},"version":{"nullable":true,"title":"Version","type":"string"}},"title":"PredictionResponse","type":"object"},"Status":{"description":"An enumeration.","enum":["starting","processing","succeeded","canceled","failed"],"title":"Status","type":"string"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"title":"Location","type":"array"},"msg":{"title":"Message","type":"string"},"type":{"title":"Error Type","type":"string"}},"required":["loc","msg","type"],"title":"ValidationError","type":"object"},"WebhookEvent":{"description":"An enumeration.","enum":["start","output","logs","completed"],"title":"WebhookEvent","type":"string"}}},"info":{"title":"Cog","version":"0.1.0"},"openapi":"3.0.2","paths":{"/":{"get":{"operationId":"root__get","responses":{"200":{"content":{"application/json":{"schema":{"title":"Response Root Get"}}},"description":"Successful Response"}},"summary":"Root"}},"/health-check":{"get":{"operationId":"healthcheck_health_check_get","responses":{"200":{"content":{"application/json":{"schema":{"title":"Response Healthcheck Health Check Get"}}},"description":"Successful Response"}},"summary":"Healthcheck"}},"/predictions":{"post":{"description":"Run a single prediction on the model","operationId":"predict_predictions_post","parameters":[{"in":"header","name":"prefer","required":false,"schema":{"title":"Prefer","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PredictionRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PredictionResponse"}}},"description":"Successful Response"},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}},"description":"Validation Error"}},"summary":"Predict"}},"/predictions/{prediction_id}":{"put":{"description":"Run a single prediction on the model (idempotent creation).","operationId":"predict_idempotent_predictions__prediction_id__put","parameters":[{"in":"path","name":"prediction_id","required":true,"schema":{"title":"Prediction ID","type":"string"}},{"in":"header","name":"prefer","required":false,"schema":{"title":"Prefer","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/PredictionRequest"}],"title":"Prediction Request"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PredictionResponse"}}},"description":"Successful Response"},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}},"description":"Validation Error"}},"summary":"Predict Idempotent"}},"/predictions/{prediction_id}/cancel":{"post":{"description":"Cancel a running prediction","operationId":"cancel_predictions__prediction_id__cancel_post","parameters":[{"in":"path","name":"prediction_id","required":true,"schema":{"title":"Prediction ID","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"title":"Response Cancel Predictions Prediction Id Cancel Post"}}},"description":"Successful Response"},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}},"description":"Validation Error"}},"summary":"Cancel"}},"/shutdown":{"post":{"operationId":"start_shutdown_shutdown_post","responses":{"200":{"content":{"application/json":{"schema":{"title":"Response Start Shutdown Shutdown Post"}}},"description":"Successful Response"}},"summary":"Start Shutdown"}}}} \ No newline at end of file +{ + "components": { + "schemas": { + "HTTPValidationError": { + "properties": { + "detail": { + "items": { "$ref": "#/components/schemas/ValidationError" }, + "title": "Detail", + "type": "array" + } + }, + "title": "HTTPValidationError", + "type": "object" + }, + "Input": { + "properties": { + "k": { + "default": 15, + "description": "Top-K results", + "title": "K", + "type": "integer" + }, + "user_input": { + "description": "Query text", + "title": "User Input", + "type": "string" + } + }, + "required": ["user_input"], + "title": "Input", + "type": "object" + }, + "Output": { + "items": { "additionalProperties": true, "type": "object" }, + "title": "Output", + "type": "array" + }, + "PredictionRequest": { + "properties": { + "context": { + "additionalProperties": { "type": "string" }, + "nullable": true, + "title": "Context", + "type": "object" + }, + "created_at": { + "format": "date-time", + "nullable": true, + "title": "Created At", + "type": "string" + }, + "id": { "nullable": true, "title": "Id", "type": "string" }, + "input": { "$ref": "#/components/schemas/Input", "nullable": true }, + "output_file_prefix": { + "nullable": true, + "title": "Output File Prefix", + "type": "string" + }, + "webhook": { + "format": "uri", + "maxLength": 65536, + "minLength": 1, + "nullable": true, + "title": "Webhook", + "type": "string" + }, + "webhook_events_filter": { + "default": ["start", "output", "logs", "completed"], + "items": { "$ref": "#/components/schemas/WebhookEvent" }, + "nullable": true, + "type": "array" + } + }, + "title": "PredictionRequest", + "type": "object" + }, + "PredictionResponse": { + "properties": { + "completed_at": { + "format": "date-time", + "nullable": true, + "title": "Completed At", + "type": "string" + }, + "created_at": { + "format": "date-time", + "nullable": true, + "title": "Created At", + "type": "string" + }, + "error": { "nullable": true, "title": "Error", "type": "string" }, + "id": { "nullable": true, "title": "Id", "type": "string" }, + "input": { "$ref": "#/components/schemas/Input", "nullable": true }, + "logs": { "default": "", "title": "Logs", "type": "string" }, + "metrics": { + "additionalProperties": true, + "nullable": true, + "title": "Metrics", + "type": "object" + }, + "output": { "$ref": "#/components/schemas/Output" }, + "started_at": { + "format": "date-time", + "nullable": true, + "title": "Started At", + "type": "string" + }, + "status": { "$ref": "#/components/schemas/Status", "nullable": true }, + "version": { "nullable": true, "title": "Version", "type": "string" } + }, + "title": "PredictionResponse", + "type": "object" + }, + "Status": { + "description": "An enumeration.", + "enum": ["starting", "processing", "succeeded", "canceled", "failed"], + "title": "Status", + "type": "string" + }, + "ValidationError": { + "properties": { + "loc": { + "items": { "anyOf": [{ "type": "string" }, { "type": "integer" }] }, + "title": "Location", + "type": "array" + }, + "msg": { "title": "Message", "type": "string" }, + "type": { "title": "Error Type", "type": "string" } + }, + "required": ["loc", "msg", "type"], + "title": "ValidationError", + "type": "object" + }, + "WebhookEvent": { + "description": "An enumeration.", + "enum": ["start", "output", "logs", "completed"], + "title": "WebhookEvent", + "type": "string" + } + } + }, + "info": { "title": "Cog", "version": "0.1.0" }, + "openapi": "3.0.2", + "paths": { + "/": { + "get": { + "operationId": "root__get", + "responses": { + "200": { + "content": { + "application/json": { + "schema": { "title": "Response Root Get" } + } + }, + "description": "Successful Response" + } + }, + "summary": "Root" + } + }, + "/health-check": { + "get": { + "operationId": "healthcheck_health_check_get", + "responses": { + "200": { + "content": { + "application/json": { + "schema": { "title": "Response Healthcheck Health Check Get" } + } + }, + "description": "Successful Response" + } + }, + "summary": "Healthcheck" + } + }, + "/predictions": { + "post": { + "description": "Run a single prediction on the model", + "operationId": "predict_predictions_post", + "parameters": [ + { + "in": "header", + "name": "prefer", + "required": false, + "schema": { "title": "Prefer", "type": "string" } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/PredictionRequest" } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/PredictionResponse" } + } + }, + "description": "Successful Response" + }, + "422": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/HTTPValidationError" } + } + }, + "description": "Validation Error" + } + }, + "summary": "Predict" + } + }, + "/predictions/{prediction_id}": { + "put": { + "description": "Run a single prediction on the model (idempotent creation).", + "operationId": "predict_idempotent_predictions__prediction_id__put", + "parameters": [ + { + "in": "path", + "name": "prediction_id", + "required": true, + "schema": { "title": "Prediction ID", "type": "string" } + }, + { + "in": "header", + "name": "prefer", + "required": false, + "schema": { "title": "Prefer", "type": "string" } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "allOf": [{ "$ref": "#/components/schemas/PredictionRequest" }], + "title": "Prediction Request" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/PredictionResponse" } + } + }, + "description": "Successful Response" + }, + "422": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/HTTPValidationError" } + } + }, + "description": "Validation Error" + } + }, + "summary": "Predict Idempotent" + } + }, + "/predictions/{prediction_id}/cancel": { + "post": { + "description": "Cancel a running prediction", + "operationId": "cancel_predictions__prediction_id__cancel_post", + "parameters": [ + { + "in": "path", + "name": "prediction_id", + "required": true, + "schema": { "title": "Prediction ID", "type": "string" } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "title": "Response Cancel Predictions Prediction Id Cancel Post" + } + } + }, + "description": "Successful Response" + }, + "422": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/HTTPValidationError" } + } + }, + "description": "Validation Error" + } + }, + "summary": "Cancel" + } + }, + "/shutdown": { + "post": { + "operationId": "start_shutdown_shutdown_post", + "responses": { + "200": { + "content": { + "application/json": { + "schema": { "title": "Response Start Shutdown Shutdown Post" } + } + }, + "description": "Successful Response" + } + }, + "summary": "Start Shutdown" + } + } + } +}