@roll-agent/octopus-agent 0.0.2 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@roll-agent/octopus-agent",
3
- "version": "0.0.2",
3
+ "version": "0.0.4",
4
4
  "description": "Octopus Sponge NL2SQL Agent",
5
5
  "license": "UNLICENSED",
6
6
  "keywords": [
package/pyproject.toml CHANGED
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "octopus-skill"
3
- version = "0.0.2"
3
+ version = "0.0.4"
4
4
  description = "Octopus Sponge NL2SQL Agent"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.11"
@@ -1,3 +1,3 @@
1
1
  from __future__ import annotations
2
2
 
3
- __version__ = "0.0.2"
3
+ __version__ = "0.0.4"
@@ -95,6 +95,9 @@ class SpongeAgent:
95
95
  )
96
96
  sql_question = _strip_result_format_instruction(user_question)
97
97
  schema = self._ensure_schema()
98
+ business_clarification = _business_metric_clarification(sql_question, schema)
99
+ if business_clarification is not None:
100
+ return _business_metric_clarification_result(business_clarification)
98
101
  schema_version = str(schema.get("schemaVersion")) if schema.get("schemaVersion") is not None else None
99
102
  repaired_sql: str | None = None
100
103
  prefer_rule_based = is_recruiting_match_effect_query(sql_question)
@@ -439,6 +442,16 @@ def _query_only_result() -> QueryResult:
439
442
  )
440
443
 
441
444
 
445
+ def _business_metric_clarification_result(answer: str) -> QueryResult:
446
+ return QueryResult(
447
+ answer=answer,
448
+ generated_sql="",
449
+ normalized_sql="",
450
+ repaired_sql=None,
451
+ validation={},
452
+ )
453
+
454
+
442
455
  def _generate_with_sampler(
443
456
  *,
444
457
  generator: SamplingSqlGenerator,
@@ -530,6 +543,71 @@ def _is_mutation_analytics_request(question: str) -> bool:
530
543
  )
531
544
 
532
545
 
546
+ def _business_metric_clarification(question: str, schema: dict[str, Any]) -> str | None:
547
+ if is_recruiting_match_effect_query(question):
548
+ return None
549
+ metric_terms = _ambiguous_business_metric_terms(question)
550
+ if not metric_terms:
551
+ return None
552
+ if _schema_has_metric_definition(question, schema, metric_terms):
553
+ return None
554
+
555
+ lines = [
556
+ "这个查询涉及业务口径,我暂时不直接生成 SQL,避免结果口径不准。",
557
+ "",
558
+ "请先确认:",
559
+ f"1. 指标定义:“{'、'.join(metric_terms)}”具体包含哪些数据?",
560
+ "2. 时间口径:按哪个时间字段统计?",
561
+ "3. 状态口径:哪些状态算有效/成功/完成/异常?",
562
+ "4. 聚合维度:需要按什么维度展示?",
563
+ ]
564
+ return "\n".join(lines)
565
+
566
+
567
+ def _ambiguous_business_metric_terms(question: str) -> list[str]:
568
+ terms = (
569
+ "漏斗",
570
+ "转化率",
571
+ "转化",
572
+ "有效",
573
+ "活跃",
574
+ "成功率",
575
+ "留存",
576
+ "履约",
577
+ "异常",
578
+ "质量",
579
+ "效率",
580
+ "趋势",
581
+ "健康度",
582
+ "达成率",
583
+ "完成率",
584
+ )
585
+ return [term for term in terms if term in question]
586
+
587
+
588
+ def _schema_has_metric_definition(question: str, schema: dict[str, Any], metric_terms: list[str]) -> bool:
589
+ metric_texts: list[str] = []
590
+ for metric in schema.get("metrics") or []:
591
+ if not isinstance(metric, dict):
592
+ continue
593
+ parts: list[str] = []
594
+ for key in ("name", "term", "displayName", "definition", "description", "aggregation"):
595
+ value = metric.get(key)
596
+ if isinstance(value, str):
597
+ parts.append(value)
598
+ filters = metric.get("filters")
599
+ if isinstance(filters, list):
600
+ parts.extend(str(item) for item in filters)
601
+ metric_text = " ".join(parts)
602
+ if metric_text:
603
+ metric_texts.append(metric_text)
604
+ name = metric.get("name")
605
+ if isinstance(name, str) and name and name in question:
606
+ return True
607
+
608
+ return any(term in metric_text for term in metric_terms for metric_text in metric_texts)
609
+
610
+
533
611
  def _apply_default_limit(sql: str, question: str, default_limit: int) -> str:
534
612
  if _question_requests_limit(question):
535
613
  return sql