sophhub 0.4.21 → 0.4.23

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.
Files changed (78) hide show
  1. package/agents/parent-toddler/.config.json +7 -1
  2. package/agents/parent-toddler/HEARTBEAT.md +4 -4
  3. package/agents/parent-toddler/TOOLS.md +9 -0
  4. package/agents/parent-toddler/scripts/compact_sessions_over_threshold.py +368 -0
  5. package/package.json +1 -1
  6. package/skills/agent-install/src/SKILL.md +2 -0
  7. package/skills/agent-install/src/scripts/common.py +20 -0
  8. package/skills/agent-install/src/scripts/update_openclaw.py +5 -0
  9. package/skills/image-classify/skill.json +12 -5
  10. package/skills/image-classify/src/SKILL.md +1 -1
  11. package/skills/image-classify/src/references/config.json +1 -1
  12. package/skills/insurance-customer-policy/skill.json +12 -0
  13. package/skills/insurance-customer-policy/src/SKILL.md +121 -0
  14. package/skills/insurance-customer-policy/src/pyproject.toml +9 -0
  15. package/skills/insurance-customer-policy/src/scripts/cli.py +16 -0
  16. package/skills/insurance-customer-policy/src/scripts/cloud_insurance_full_test.py +785 -0
  17. package/skills/insurance-customer-policy/src/scripts/dashboard_all.py +205 -0
  18. package/skills/insurance-customer-policy/src/scripts/insurance_customer_cli/__init__.py +0 -0
  19. package/skills/insurance-customer-policy/src/scripts/insurance_customer_cli/__main__.py +4 -0
  20. package/skills/insurance-customer-policy/src/scripts/insurance_customer_cli/cli.py +816 -0
  21. package/skills/insurance-customer-policy/src/scripts/insurance_customer_cli/db.py +181 -0
  22. package/skills/insurance-customer-policy/src/scripts/insurance_customer_cli/insurance_paths.py +184 -0
  23. package/skills/insurance-customer-policy/src/scripts/run_e2e_smoke.py +164 -0
  24. package/skills/insurance-customer-policy/src/scripts/test_cloud_zero_config.py +217 -0
  25. package/skills/insurance-customer-policy/src/scripts/test_dashboard_all.py +113 -0
  26. package/skills/insurance-customer-policy/src/src/insurance_customer_cli/__init__.py +0 -0
  27. package/skills/insurance-customer-policy/src/src/insurance_customer_cli/__main__.py +4 -0
  28. package/skills/insurance-customer-policy/src/src/insurance_customer_cli/cli.py +816 -0
  29. package/skills/insurance-customer-policy/src/src/insurance_customer_cli/db.py +181 -0
  30. package/skills/insurance-customer-policy/src/src/insurance_customer_cli/insurance_paths.py +184 -0
  31. package/skills/insurance-product-analysis/skill.json +12 -0
  32. package/skills/insurance-product-analysis/src/SKILL.md +99 -0
  33. package/skills/insurance-product-analysis/src/pyproject.toml +9 -0
  34. package/skills/insurance-product-analysis/src/scripts/cli.py +16 -0
  35. package/skills/insurance-product-analysis/src/scripts/insurance_product_cli/__init__.py +0 -0
  36. package/skills/insurance-product-analysis/src/scripts/insurance_product_cli/__main__.py +4 -0
  37. package/skills/insurance-product-analysis/src/scripts/insurance_product_cli/cli.py +545 -0
  38. package/skills/insurance-product-analysis/src/scripts/insurance_product_cli/db.py +180 -0
  39. package/skills/insurance-product-analysis/src/scripts/insurance_product_cli/orchestrator.py +163 -0
  40. package/skills/insurance-product-analysis/src/scripts/run_e2e_smoke.py +202 -0
  41. package/skills/insurance-product-analysis/src/src/insurance_product_cli/__init__.py +0 -0
  42. package/skills/insurance-product-analysis/src/src/insurance_product_cli/__main__.py +4 -0
  43. package/skills/insurance-product-analysis/src/src/insurance_product_cli/cli.py +545 -0
  44. package/skills/insurance-product-analysis/src/src/insurance_product_cli/db.py +180 -0
  45. package/skills/insurance-product-analysis/src/src/insurance_product_cli/orchestrator.py +163 -0
  46. package/skills/insurance-sales-pipeline/skill.json +12 -0
  47. package/skills/insurance-sales-pipeline/src/SKILL.md +102 -0
  48. package/skills/insurance-sales-pipeline/src/pyproject.toml +9 -0
  49. package/skills/insurance-sales-pipeline/src/scripts/cli.py +16 -0
  50. package/skills/insurance-sales-pipeline/src/scripts/insurance_pipeline_cli/__init__.py +0 -0
  51. package/skills/insurance-sales-pipeline/src/scripts/insurance_pipeline_cli/__main__.py +4 -0
  52. package/skills/insurance-sales-pipeline/src/scripts/insurance_pipeline_cli/cli.py +496 -0
  53. package/skills/insurance-sales-pipeline/src/scripts/insurance_pipeline_cli/db.py +180 -0
  54. package/skills/insurance-sales-pipeline/src/scripts/insurance_pipeline_cli/orchestrator.py +36 -0
  55. package/skills/insurance-sales-pipeline/src/scripts/run_e2e_smoke.py +208 -0
  56. package/skills/insurance-sales-pipeline/src/src/insurance_pipeline_cli/__init__.py +0 -0
  57. package/skills/insurance-sales-pipeline/src/src/insurance_pipeline_cli/__main__.py +4 -0
  58. package/skills/insurance-sales-pipeline/src/src/insurance_pipeline_cli/cli.py +496 -0
  59. package/skills/insurance-sales-pipeline/src/src/insurance_pipeline_cli/db.py +180 -0
  60. package/skills/insurance-sales-pipeline/src/src/insurance_pipeline_cli/orchestrator.py +36 -0
  61. package/skills/insurance-schedule-renewal/skill.json +12 -0
  62. package/skills/insurance-schedule-renewal/src/SKILL.md +94 -0
  63. package/skills/insurance-schedule-renewal/src/pyproject.toml +9 -0
  64. package/skills/insurance-schedule-renewal/src/scripts/cli.py +16 -0
  65. package/skills/insurance-schedule-renewal/src/scripts/insurance_schedule_cli/__init__.py +0 -0
  66. package/skills/insurance-schedule-renewal/src/scripts/insurance_schedule_cli/__main__.py +4 -0
  67. package/skills/insurance-schedule-renewal/src/scripts/insurance_schedule_cli/cli.py +429 -0
  68. package/skills/insurance-schedule-renewal/src/scripts/insurance_schedule_cli/db.py +180 -0
  69. package/skills/insurance-schedule-renewal/src/scripts/insurance_schedule_cli/orchestrator.py +94 -0
  70. package/skills/insurance-schedule-renewal/src/scripts/run_e2e_smoke.py +218 -0
  71. package/skills/insurance-schedule-renewal/src/src/insurance_schedule_cli/__init__.py +0 -0
  72. package/skills/insurance-schedule-renewal/src/src/insurance_schedule_cli/__main__.py +4 -0
  73. package/skills/insurance-schedule-renewal/src/src/insurance_schedule_cli/cli.py +429 -0
  74. package/skills/insurance-schedule-renewal/src/src/insurance_schedule_cli/db.py +180 -0
  75. package/skills/insurance-schedule-renewal/src/src/insurance_schedule_cli/orchestrator.py +94 -0
  76. package/skills/insurance-shared-data/skill.json +20 -0
  77. package/skills/insurance-shared-data/src/SKILL.md +33 -0
  78. package/skills/insurance-shared-data/src/scripts/cloud_insurance_super_test.py +246 -0
@@ -0,0 +1,205 @@
1
+ #!/usr/bin/env python3
2
+ """Aggregate insurance overview directly from shared insurance.sqlite3."""
3
+ from __future__ import annotations
4
+
5
+ import argparse
6
+ import json
7
+ import sys
8
+ from pathlib import Path
9
+ from typing import Any
10
+
11
+ SCRIPTS_DIR = Path(__file__).resolve().parent
12
+ if str(SCRIPTS_DIR) not in sys.path:
13
+ sys.path.insert(0, str(SCRIPTS_DIR))
14
+
15
+ from insurance_customer_cli import db
16
+
17
+
18
+ def aggregate() -> dict[str, Any]:
19
+ conn = db.connect()
20
+ month = conn.execute("SELECT strftime('%Y-%m','now','localtime') AS m").fetchone()["m"]
21
+ start = f"{month}-01 00:00:00"
22
+ y, m = map(int, month.split("-"))
23
+ end = f"{y + 1:04d}-01-01 00:00:00" if m == 12 else f"{y:04d}-{m + 1:02d}-01 00:00:00"
24
+
25
+ customers_total = int(conn.execute("SELECT COUNT(*) AS n FROM customers WHERE status='active'").fetchone()["n"])
26
+ hi_value = int(
27
+ conn.execute(
28
+ """
29
+ SELECT COUNT(*) AS n FROM (
30
+ SELECT c.id, COALESCE(SUM(p.premium),0) AS annual
31
+ FROM customers c
32
+ LEFT JOIN policies p ON p.customer_id=c.id AND p.status='active'
33
+ WHERE c.status='active'
34
+ GROUP BY c.id
35
+ HAVING annual > 50000
36
+ )
37
+ """
38
+ ).fetchone()["n"]
39
+ )
40
+ active = int(
41
+ conn.execute(
42
+ """
43
+ SELECT COUNT(DISTINCT customer_id) AS n
44
+ FROM followups
45
+ WHERE created_at >= datetime('now','-30 days')
46
+ """
47
+ ).fetchone()["n"]
48
+ )
49
+ new = int(
50
+ conn.execute(
51
+ "SELECT COUNT(*) AS n FROM customers WHERE status='active' AND created_at >= datetime('now','-30 days')"
52
+ ).fetchone()["n"]
53
+ )
54
+ dormant = int(
55
+ conn.execute(
56
+ """
57
+ SELECT COUNT(*) AS n
58
+ FROM customers c
59
+ WHERE c.status='active'
60
+ AND c.created_at < datetime('now','-60 days')
61
+ AND COALESCE(
62
+ (SELECT MAX(f.created_at) FROM followups f WHERE f.customer_id=c.id),
63
+ c.created_at
64
+ ) < datetime('now','-60 days')
65
+ """
66
+ ).fetchone()["n"]
67
+ )
68
+ policies_total = int(conn.execute("SELECT COUNT(*) AS n FROM policies WHERE status='active'").fetchone()["n"])
69
+ total_premium = float(
70
+ conn.execute("SELECT COALESCE(SUM(premium),0) AS s FROM policies WHERE status='active'").fetchone()["s"]
71
+ )
72
+ products_total = int(conn.execute("SELECT COUNT(*) AS n FROM products WHERE status='active'").fetchone()["n"])
73
+ renewal_30d = int(
74
+ conn.execute(
75
+ """
76
+ SELECT COUNT(*) AS n FROM policies
77
+ WHERE status='active'
78
+ AND (
79
+ (expire_date IS NOT NULL AND expire_date<>'' AND expire_date<=date('now','+30 days') AND expire_date>=date('now'))
80
+ OR
81
+ (next_pay_date IS NOT NULL AND next_pay_date<>'' AND next_pay_date<=date('now','+30 days') AND next_pay_date>=date('now'))
82
+ )
83
+ """
84
+ ).fetchone()["n"]
85
+ )
86
+ followup_30d_lapsed = int(
87
+ conn.execute(
88
+ """
89
+ SELECT COUNT(*) AS n
90
+ FROM customers c
91
+ WHERE c.status='active'
92
+ AND COALESCE(
93
+ (SELECT MAX(f.created_at) FROM followups f WHERE f.customer_id=c.id),
94
+ c.created_at
95
+ ) < datetime('now','-30 days')
96
+ """
97
+ ).fetchone()["n"]
98
+ )
99
+ dormant_60d = dormant
100
+ active_deals = int(
101
+ conn.execute(
102
+ "SELECT COUNT(*) AS n FROM deals WHERE stage IN ('在谈','方案中','议价')"
103
+ ).fetchone()["n"]
104
+ )
105
+ this_month_target = float(
106
+ (conn.execute("SELECT target_premium FROM monthly_targets WHERE month=?", (month,)).fetchone() or {"target_premium": 0})[
107
+ "target_premium"
108
+ ]
109
+ )
110
+ this_month_closed = float(
111
+ conn.execute(
112
+ """
113
+ SELECT COALESCE(SUM(COALESCE(actual_premium, estimated_premium, 0)),0) AS s
114
+ FROM deals
115
+ WHERE stage='已成交' AND closed_at >= ? AND closed_at < ?
116
+ """,
117
+ (start, end),
118
+ ).fetchone()["s"]
119
+ )
120
+ this_month_forecast = float(
121
+ conn.execute(
122
+ """
123
+ SELECT COALESCE(SUM(
124
+ CASE
125
+ WHEN stage='在谈' THEN estimated_premium * 0.20
126
+ WHEN stage='方案中' THEN estimated_premium * 0.50
127
+ WHEN stage='议价' THEN estimated_premium * 0.80
128
+ ELSE 0
129
+ END
130
+ ),0) AS s
131
+ FROM deals
132
+ """
133
+ ).fetchone()["s"]
134
+ )
135
+
136
+ overview = {
137
+ "customers_total": customers_total,
138
+ "hi_value": hi_value,
139
+ "active": active,
140
+ "dormant": dormant,
141
+ "new": new,
142
+ "policies_total": policies_total,
143
+ "total_premium": total_premium,
144
+ "products_total": products_total,
145
+ "renewal_30d": renewal_30d,
146
+ "followup_30d_lapsed": followup_30d_lapsed,
147
+ "dormant_60d": dormant_60d,
148
+ "this_month": month,
149
+ "active_deals": active_deals,
150
+ "this_month_target": this_month_target,
151
+ "this_month_closed": this_month_closed,
152
+ "this_month_forecast": this_month_forecast,
153
+ }
154
+
155
+ md_lines: list[str] = []
156
+ month_label = overview.get("this_month", "")
157
+ md_lines.append(f"🛡️ **经营概览({month_label})**" if month_label else "🛡️ **经营概览**")
158
+ md_lines.append("")
159
+ md_lines.append(
160
+ f"👥 客户:{overview['customers_total']}人(高净值{overview['hi_value']} / "
161
+ f"活跃{overview['active']} / 沉睡{overview['dormant']} / 新客{overview['new']})"
162
+ )
163
+ md_lines.append(
164
+ f"📋 保单:{overview['policies_total']}份(总保费约¥{overview['total_premium']:,.0f})"
165
+ )
166
+ md_lines.append(f"📦 产品库:{overview['products_total']} 款")
167
+ md_lines.append(f"⏰ 本月续保:{overview['renewal_30d']}份 30 天内到期")
168
+ md_lines.append(
169
+ f"🎯 本月目标:保费¥{overview['this_month_target']:,.0f} | "
170
+ f"已完成:¥{overview['this_month_closed']:,.0f} | "
171
+ f"在谈预估:¥{overview['this_month_forecast']:,.0f} | "
172
+ f"在谈商机:{overview['active_deals']}单"
173
+ )
174
+ md_lines.append("")
175
+ md_lines.append("⚠️ 待处理:")
176
+ md_lines.append(f"- {overview['renewal_30d']} 份保单 30 天内到期")
177
+ md_lines.append(f"- {overview['followup_30d_lapsed']} 位客户超 30 天未联系")
178
+ md_lines.append(f"- {overview['dormant_60d']} 位客户超 60 天未联系(沉睡)")
179
+
180
+ conn.close()
181
+ return {"ok": True, "overview": overview, "skills": {"source": "shared-db"}, "markdown": "\n".join(md_lines)}
182
+
183
+
184
+ def main(argv: list[str] | None = None) -> int:
185
+ parser = argparse.ArgumentParser(prog="dashboard_all")
186
+ parser.add_argument("--json", action="store_true",
187
+ help="只输出 JSON(默认就是 JSON;保留参数对齐子命令风格)")
188
+ parser.add_argument("--md", action="store_true",
189
+ help="只打印 markdown 卡片(不打 JSON)")
190
+ args = parser.parse_args(argv)
191
+ try:
192
+ sys.stdout.reconfigure(encoding="utf-8")
193
+ sys.stderr.reconfigure(encoding="utf-8")
194
+ except (AttributeError, OSError):
195
+ pass
196
+ data = aggregate()
197
+ if args.md:
198
+ print(data["markdown"])
199
+ else:
200
+ print(json.dumps(data, ensure_ascii=False, indent=2))
201
+ return 0
202
+
203
+
204
+ if __name__ == "__main__":
205
+ raise SystemExit(main())
@@ -0,0 +1,4 @@
1
+ from insurance_customer_cli.cli import main
2
+
3
+ if __name__ == "__main__":
4
+ raise SystemExit(main())