railwise-ai 1.2.32 → 1.2.34

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 (173) hide show
  1. package/agent-pack/README.md +16 -0
  2. package/agent-pack/assets/agent/chief_manager.md +69 -0
  3. package/agent-pack/assets/agent/commercial_specialist.md +47 -0
  4. package/agent-pack/assets/agent/data_analyst.md +54 -0
  5. package/agent-pack/assets/agent/docs.md +38 -0
  6. package/agent-pack/assets/agent/duplicate-pr.md +25 -0
  7. package/agent-pack/assets/agent/qa_inspector.md +58 -0
  8. package/agent-pack/assets/agent/qa_reviewer.md +57 -0
  9. package/agent-pack/assets/agent/solution_architect.md +53 -0
  10. package/agent-pack/assets/agent/technical_writer.md +61 -0
  11. package/agent-pack/assets/agent/translator.md +34 -0
  12. package/agent-pack/assets/agent/triage.md +139 -0
  13. package/agent-pack/assets/command/ai-deps.md +24 -0
  14. package/agent-pack/assets/command/bid-intel.md +29 -0
  15. package/agent-pack/assets/command/bid-prepare.md +24 -0
  16. package/agent-pack/assets/command/commit.md +37 -0
  17. package/agent-pack/assets/command/daily-report.md +26 -0
  18. package/agent-pack/assets/command/data-check.md +22 -0
  19. package/agent-pack/assets/command/emergency-response.md +66 -0
  20. package/agent-pack/assets/command/issues.md +23 -0
  21. package/agent-pack/assets/command/learn.md +42 -0
  22. package/agent-pack/assets/command/monthly-report.md +35 -0
  23. package/agent-pack/assets/command/payment-reminder.md +27 -0
  24. package/agent-pack/assets/command/plan-draft.md +28 -0
  25. package/agent-pack/assets/command/review-response.md +23 -0
  26. package/agent-pack/assets/command/rmslop.md +15 -0
  27. package/agent-pack/assets/command/safety-check.md +20 -0
  28. package/agent-pack/assets/command/spellcheck.md +5 -0
  29. package/agent-pack/assets/command/trend-analysis.md +38 -0
  30. package/agent-pack/assets/command/weekly-report.md +28 -0
  31. package/agent-pack/assets/lib/os_api.ts +100 -0
  32. package/agent-pack/assets/skill/adjustment-report/SKILL.md +88 -0
  33. package/agent-pack/assets/skill/approval-flow-intelligence/SKILL.md +123 -0
  34. package/agent-pack/assets/skill/bidding-knowledge/SKILL.md +98 -0
  35. package/agent-pack/assets/skill/bun-file-io/SKILL.md +42 -0
  36. package/agent-pack/assets/skill/business-finance/SKILL.md +91 -0
  37. package/agent-pack/assets/skill/business-operations-analytics/SKILL.md +120 -0
  38. package/agent-pack/assets/skill/cad-bim-review/SKILL.md +84 -0
  39. package/agent-pack/assets/skill/canvas-design/SKILL.md +141 -0
  40. package/agent-pack/assets/skill/construction-monitoring/SKILL.md +89 -0
  41. package/agent-pack/assets/skill/customer-portal-brief/SKILL.md +121 -0
  42. package/agent-pack/assets/skill/data-analysis/SKILL.md +79 -0
  43. package/agent-pack/assets/skill/di-bao-monitoring/SKILL.md +680 -0
  44. package/agent-pack/assets/skill/di-bao-monitoring/agents/openai.yaml +4 -0
  45. package/agent-pack/assets/skill/di-bao-monitoring/assets/crossing-static-level-input-template.csv +2 -0
  46. package/agent-pack/assets/skill/di-bao-monitoring/assets/crossing-total-station-input-template.csv +2 -0
  47. package/agent-pack/assets/skill/di-bao-monitoring/assets/crossing-total-station-report-template.md +59 -0
  48. package/agent-pack/assets/skill/di-bao-monitoring/assets/daily-report-template.md +90 -0
  49. package/agent-pack/assets/skill/di-bao-monitoring/assets/data-input-template.csv +2 -0
  50. package/agent-pack/assets/skill/di-bao-monitoring/assets/initial-value-report-template.md +92 -0
  51. package/agent-pack/assets/skill/di-bao-monitoring/assets/monthly-report-template.md +103 -0
  52. package/agent-pack/assets/skill/di-bao-monitoring/assets/plan-template.md +673 -0
  53. package/agent-pack/assets/skill/di-bao-monitoring/assets/point-alias-map-template.json +25 -0
  54. package/agent-pack/assets/skill/di-bao-monitoring/assets/project-brief-template.md +59 -0
  55. package/agent-pack/assets/skill/di-bao-monitoring/assets/project-summary-template.md +154 -0
  56. package/agent-pack/assets/skill/di-bao-monitoring/assets/warning-notice-template.md +58 -0
  57. package/agent-pack/assets/skill/di-bao-monitoring/assets/weekly-report-template.md +49 -0
  58. package/agent-pack/assets/skill/di-bao-monitoring/assets//345/256/214/346/225/264/346/212/245/350/241/250/346/250/241/346/235/277.xlsx +0 -0
  59. package/agent-pack/assets/skill/di-bao-monitoring/assets//345/277/253/346/212/245/346/250/241/346/235/277.xlsx +0 -0
  60. package/agent-pack/assets/skill/di-bao-monitoring/references/crossing-static-level-report.md +115 -0
  61. package/agent-pack/assets/skill/di-bao-monitoring/references/crossing-total-station-report.md +206 -0
  62. package/agent-pack/assets/skill/di-bao-monitoring/references/data-processing.md +170 -0
  63. package/agent-pack/assets/skill/di-bao-monitoring/references/elevated-line.md +319 -0
  64. package/agent-pack/assets/skill/di-bao-monitoring/references/initial-and-summary-workflow.md +222 -0
  65. package/agent-pack/assets/skill/di-bao-monitoring/references/key-difficulties.md +216 -0
  66. package/agent-pack/assets/skill/di-bao-monitoring/references/monitoring-catalog.md +80 -0
  67. package/agent-pack/assets/skill/di-bao-monitoring/references/phase0-intake.md +169 -0
  68. package/agent-pack/assets/skill/di-bao-monitoring/references/phase1-drafting.md +185 -0
  69. package/agent-pack/assets/skill/di-bao-monitoring/references/phase2-internal-review.md +166 -0
  70. package/agent-pack/assets/skill/di-bao-monitoring/references/report-workflow.md +181 -0
  71. package/agent-pack/assets/skill/di-bao-monitoring/references/review-checklist.md +140 -0
  72. package/agent-pack/assets/skill/di-bao-monitoring/references/review-response-template.md +87 -0
  73. package/agent-pack/assets/skill/di-bao-monitoring/references/scoping-and-pricing.md +214 -0
  74. package/agent-pack/assets/skill/di-bao-monitoring/references/source-analysis.md +137 -0
  75. package/agent-pack/assets/skill/di-bao-monitoring/references/technical-standards.md +188 -0
  76. package/agent-pack/assets/skill/di-bao-monitoring/references/toc-template-A.md +142 -0
  77. package/agent-pack/assets/skill/di-bao-monitoring/references/toc-template-B.md +100 -0
  78. package/agent-pack/assets/skill/di-bao-monitoring/references/warning-workflow.md +63 -0
  79. package/agent-pack/assets/skill/di-bao-monitoring/scripts/build_crossing_total_station_xlsx.py +2438 -0
  80. package/agent-pack/assets/skill/di-bao-monitoring/scripts/evaluate_alarms.py +215 -0
  81. package/agent-pack/assets/skill/di-bao-monitoring/scripts/fetch_adjusted_total_station.py +946 -0
  82. package/agent-pack/assets/skill/di-bao-monitoring/scripts/fetch_shhh_static_level.py +556 -0
  83. package/agent-pack/assets/skill/di-bao-monitoring/scripts/run_crossing_4h_report.sh +141 -0
  84. package/agent-pack/assets/skill/di-bao-monitoring/scripts/summarize_crossing_total_station.py +303 -0
  85. package/agent-pack/assets/skill/docx-generation/SKILL.md +141 -0
  86. package/agent-pack/assets/skill/excel-operations/SKILL.md +121 -0
  87. package/agent-pack/assets/skill/frontend-design/SKILL.md +151 -0
  88. package/agent-pack/assets/skill/humanizer/SKILL.md +90 -0
  89. package/agent-pack/assets/skill/monitoring-design/SKILL.md +100 -0
  90. package/agent-pack/assets/skill/operational-monitoring/SKILL.md +135 -0
  91. package/agent-pack/assets/skill/operational-monitoring/assets/checklists/archive-self-check.md +54 -0
  92. package/agent-pack/assets/skill/operational-monitoring/assets/schemas/convergence-result-table.csv +5 -0
  93. package/agent-pack/assets/skill/operational-monitoring/assets/schemas/horizontal-result-table.csv +3 -0
  94. package/agent-pack/assets/skill/operational-monitoring/assets/schemas/settlement-result-table.csv +7 -0
  95. package/agent-pack/assets/skill/operational-monitoring/assets/scripts/init-archive-tree.sh +65 -0
  96. package/agent-pack/assets/skill/operational-monitoring/assets/templates/control-network-report.md +102 -0
  97. package/agent-pack/assets/skill/operational-monitoring/assets/templates/daily-log.md +47 -0
  98. package/agent-pack/assets/skill/operational-monitoring/assets/templates/i-angle-check.md +38 -0
  99. package/agent-pack/assets/skill/operational-monitoring/assets/templates/monitoring-scheme.md +234 -0
  100. package/agent-pack/assets/skill/operational-monitoring/assets/templates/period-report.md +95 -0
  101. package/agent-pack/assets/skill/operational-monitoring/assets/templates/point-acceptance-record.md +51 -0
  102. package/agent-pack/assets/skill/operational-monitoring/assets/templates/point-installation-record.md +38 -0
  103. package/agent-pack/assets/skill/operational-monitoring/assets/templates/summary-report.md +89 -0
  104. package/agent-pack/assets/skill/operational-monitoring/assets/templates/warning-bulletin.md +61 -0
  105. package/agent-pack/assets/skill/operational-monitoring/assets/templates/weekly-monthly-report.md +46 -0
  106. package/agent-pack/assets/skill/operational-monitoring/references/archive-and-delivery.md +146 -0
  107. package/agent-pack/assets/skill/operational-monitoring/references/baseline-network.md +131 -0
  108. package/agent-pack/assets/skill/operational-monitoring/references/convergence-monitoring.md +134 -0
  109. package/agent-pack/assets/skill/operational-monitoring/references/data-processing.md +178 -0
  110. package/agent-pack/assets/skill/operational-monitoring/references/horizontal-displacement.md +128 -0
  111. package/agent-pack/assets/skill/operational-monitoring/references/monitoring-points.md +132 -0
  112. package/agent-pack/assets/skill/operational-monitoring/references/monitoring-scheme.md +178 -0
  113. package/agent-pack/assets/skill/operational-monitoring/references/period-report.md +108 -0
  114. package/agent-pack/assets/skill/operational-monitoring/references/regulations-and-frequency.md +127 -0
  115. package/agent-pack/assets/skill/operational-monitoring/references/settlement-monitoring.md +116 -0
  116. package/agent-pack/assets/skill/operational-monitoring/references/summary-report.md +128 -0
  117. package/agent-pack/assets/skill/operational-monitoring/references/warning-and-disposal.md +118 -0
  118. package/agent-pack/assets/skill/ops-monitoring/SKILL.md +93 -0
  119. package/agent-pack/assets/skill/railwise-knowledge-curation/SKILL.md +92 -0
  120. package/agent-pack/assets/skill/report-dibao/SKILL.md +60 -0
  121. package/agent-pack/assets/skill/report-writing/SKILL.md +103 -0
  122. package/agent-pack/assets/skill/resource-dispatch-intelligence/SKILL.md +125 -0
  123. package/agent-pack/assets/skill/standard-reference/SKILL.md +101 -0
  124. package/agent-pack/assets/skill/weekly-work-intelligence/SKILL.md +123 -0
  125. package/agent-pack/assets/template/adjustment-trend.json +53 -0
  126. package/agent-pack/assets/template/bid-technical-proposal.json +42 -0
  127. package/agent-pack/assets/template/compliance-review.json +35 -0
  128. package/agent-pack/assets/template/daily-monitor-report.json +34 -0
  129. package/agent-pack/assets/template/field-data-qa.json +47 -0
  130. package/agent-pack/assets/template/monitoring-plan.json +28 -0
  131. package/agent-pack/assets/template/monthly-monitor-report.json +47 -0
  132. package/agent-pack/assets/template/project-ppt.json +47 -0
  133. package/agent-pack/assets/template/review-response.json +28 -0
  134. package/agent-pack/assets/template/schema.json +72 -0
  135. package/agent-pack/assets/template/weekly-monitor-report.json +33 -0
  136. package/agent-pack/assets/theme/mytheme.json +223 -0
  137. package/agent-pack/assets/tool/angle_convert.ts +151 -0
  138. package/agent-pack/assets/tool/axial_force.ts +186 -0
  139. package/agent-pack/assets/tool/chart_generator.ts +185 -0
  140. package/agent-pack/assets/tool/control_network.ts +413 -0
  141. package/agent-pack/assets/tool/coord_transform.ts +333 -0
  142. package/agent-pack/assets/tool/cpiii_adjustment.ts +446 -0
  143. package/agent-pack/assets/tool/cross_section.ts +356 -0
  144. package/agent-pack/assets/tool/deformation_rate.ts +234 -0
  145. package/agent-pack/assets/tool/distance_calculator.ts +239 -0
  146. package/agent-pack/assets/tool/excel_export.ts +494 -0
  147. package/agent-pack/assets/tool/format_parser.ts +181 -0
  148. package/agent-pack/assets/tool/github-pr-search.ts +57 -0
  149. package/agent-pack/assets/tool/github-pr-search.txt +10 -0
  150. package/agent-pack/assets/tool/github-triage.ts +113 -0
  151. package/agent-pack/assets/tool/github-triage.txt +6 -0
  152. package/agent-pack/assets/tool/inclinometer.ts +248 -0
  153. package/agent-pack/assets/tool/monitoring_csv.ts +120 -0
  154. package/agent-pack/assets/tool/os_contract_query.ts +63 -0
  155. package/agent-pack/assets/tool/os_dibao_project_files.ts +75 -0
  156. package/agent-pack/assets/tool/os_file_download_ref.ts +48 -0
  157. package/agent-pack/assets/tool/os_file_preview.ts +46 -0
  158. package/agent-pack/assets/tool/os_gbrain_think.ts +31 -0
  159. package/agent-pack/assets/tool/os_ppt_generate.ts +37 -0
  160. package/agent-pack/assets/tool/os_project_context.ts +24 -0
  161. package/agent-pack/assets/tool/os_report_publish.ts +28 -0
  162. package/agent-pack/assets/tool/os_wiki_ingest.ts +38 -0
  163. package/agent-pack/assets/tool/os_wiki_query.ts +26 -0
  164. package/agent-pack/assets/tool/pile_stakeout.ts +299 -0
  165. package/agent-pack/assets/tool/report_export.ts +279 -0
  166. package/agent-pack/assets/tool/shield_guidance.ts +311 -0
  167. package/agent-pack/assets/tool/standard_query.ts +391 -0
  168. package/agent-pack/assets/tool/survey_calculator.ts +415 -0
  169. package/agent-pack/assets/tool/water_level.ts +209 -0
  170. package/agent-pack/bin/install.js +183 -0
  171. package/agent-pack/package.json +695 -0
  172. package/package.json +14 -8
  173. package/postinstall.mjs +53 -22
@@ -0,0 +1,415 @@
1
+ /// <reference path="../env.d.ts" />
2
+ import { tool } from "nb-railwise/tool"
3
+
4
+ const LEVELING_LIMITS: Record<string, { k: number; unit: string; desc: string }> = {
5
+ "1st": { k: 4, unit: "mm", desc: "一等水准" },
6
+ "2nd": { k: 6, unit: "mm", desc: "二等水准(城市轨道交通监测基准网常用)" },
7
+ "3rd": { k: 12, unit: "mm", desc: "三等水准" },
8
+ "4th": { k: 20, unit: "mm", desc: "四等水准" },
9
+ "city-2nd": { k: 8, unit: "mm", desc: "城市二等水准" },
10
+ }
11
+
12
+ const TRAVERSE_ANGULAR_LIMITS: Record<string, { k: number; desc: string }> = {
13
+ DJ1: { k: 5, desc: "DJ1 经纬仪" },
14
+ DJ2: { k: 10, desc: "DJ2 经纬仪(城市测量常用)" },
15
+ DJ6: { k: 20, desc: "DJ6 经纬仪" },
16
+ }
17
+
18
+ export const leveling_closure = tool({
19
+ description:
20
+ "计算水准测量的高程闭合差是否在规范限差内。当需要判断外业水准数据是否合格时,必须调用此工具,绝不能自己口算或估算。",
21
+ args: {
22
+ measuredError: tool.schema.number().describe("现场实际测算出的高程闭合差,单位为毫米(mm),允许负值"),
23
+ routeLengthKm: tool.schema.number().positive().describe("水准路线的总长度,单位为公里(km)"),
24
+ order: tool.schema
25
+ .enum(["1st", "2nd", "3rd", "4th", "city-2nd"])
26
+ .default("4th")
27
+ .describe("测量等级:1st=一等, 2nd=二等, 3rd=三等, 4th=四等, city-2nd=城市二等"),
28
+ },
29
+ async execute(args) {
30
+ const spec = LEVELING_LIMITS[args.order]!
31
+ const limit = spec.k * Math.sqrt(args.routeLengthKm)
32
+ const pass = Math.abs(args.measuredError) <= limit
33
+
34
+ return JSON.stringify({
35
+ measured_error_mm: args.measuredError,
36
+ allowed_limit_mm: Number(limit.toFixed(3)),
37
+ order_desc: spec.desc,
38
+ formula: `±${spec.k}√L = ±${spec.k}×√${args.routeLengthKm} = ±${limit.toFixed(3)} mm`,
39
+ is_passed: pass,
40
+ ratio_pct: Number(((Math.abs(args.measuredError) / limit) * 100).toFixed(1)),
41
+ message: pass
42
+ ? `✅ 合格:实测闭合差 ${args.measuredError}mm,限差 ±${limit.toFixed(3)}mm,占限差比例 ${((Math.abs(args.measuredError) / limit) * 100).toFixed(1)}%`
43
+ : `❌ 超限:实测闭合差 ${args.measuredError}mm,限差 ±${limit.toFixed(3)}mm,超出限差 ${(Math.abs(args.measuredError) - limit).toFixed(3)}mm,必须返工重测!`,
44
+ })
45
+ },
46
+ })
47
+
48
+ export const traverse_closure = tool({
49
+ description: "计算附合导线或闭合导线的角度闭合差是否满足规范限差。调用前请确认仪器等级和测站数量。",
50
+ args: {
51
+ measuredAngularError: tool.schema.number().describe("实测角度闭合差,单位为角秒(″),允许负值"),
52
+ stationCount: tool.schema.int().positive().describe("导线测站总数(转折点数量,不含起始点)"),
53
+ instrument: tool.schema.enum(["DJ1", "DJ2", "DJ6"]).default("DJ2").describe("使用的经纬仪等级:DJ1/DJ2/DJ6"),
54
+ },
55
+ async execute(args) {
56
+ const spec = TRAVERSE_ANGULAR_LIMITS[args.instrument]!
57
+ const limit = spec.k * Math.sqrt(args.stationCount)
58
+ const pass = Math.abs(args.measuredAngularError) <= limit
59
+
60
+ return JSON.stringify({
61
+ measured_error_arcsec: args.measuredAngularError,
62
+ allowed_limit_arcsec: Number(limit.toFixed(1)),
63
+ instrument_desc: spec.desc,
64
+ formula: `±${spec.k}″√n = ±${spec.k}×√${args.stationCount} = ±${limit.toFixed(1)}″`,
65
+ is_passed: pass,
66
+ message: pass
67
+ ? `✅ 合格:角度闭合差 ${args.measuredAngularError}″,限差 ±${limit.toFixed(1)}″`
68
+ : `❌ 超限:角度闭合差 ${args.measuredAngularError}″,限差 ±${limit.toFixed(1)}″,超出 ${(Math.abs(args.measuredAngularError) - limit).toFixed(1)}″,必须返工重测!`,
69
+ })
70
+ },
71
+ })
72
+
73
+ export const alert_level = tool({
74
+ description: "根据监测点当前累计变化量和控制指标,计算预警等级。自动判断属于蓝色提示/黄色预警/红色报警/正常。",
75
+ args: {
76
+ cumulativeValue: tool.schema.number().describe("当前累计变化量绝对值,单位 mm(取绝对值传入)"),
77
+ alertThreshold: tool.schema.number().positive().describe("规范规定的报警控制值(红线),单位 mm"),
78
+ pointId: tool.schema.string().describe("测点编号,如 JC-01"),
79
+ },
80
+ async execute(args) {
81
+ const ratio = args.cumulativeValue / args.alertThreshold
82
+ let level: string
83
+ let color: string
84
+ let action: string
85
+
86
+ if (ratio >= 1.0) {
87
+ level = "红色报警"
88
+ color = "🔴"
89
+ action = "立即启动应急预案,暂停施工,通知各方负责人到场处置"
90
+ } else if (ratio >= 0.85) {
91
+ level = "橙色预警"
92
+ color = "🟠"
93
+ action = "通知项目负责人和监理,加密监测频率至每日2次,加强人工巡视"
94
+ } else if (ratio >= 0.7) {
95
+ level = "黄色预警"
96
+ color = "🟡"
97
+ action = "加密监测频率,关注发展趋势,准备上报项目部"
98
+ } else {
99
+ level = "正常"
100
+ color = "🟢"
101
+ action = "按正常频率继续监测"
102
+ }
103
+
104
+ return JSON.stringify({
105
+ point_id: args.pointId,
106
+ cumulative_value_mm: args.cumulativeValue,
107
+ alert_threshold_mm: args.alertThreshold,
108
+ ratio_pct: Number((ratio * 100).toFixed(1)),
109
+ level,
110
+ color,
111
+ action,
112
+ message: `${color} ${args.pointId}:累计变化量 ${args.cumulativeValue}mm,占控制值比例 ${(ratio * 100).toFixed(1)}%,${level}。建议措施:${action}`,
113
+ })
114
+ },
115
+ })
116
+
117
+ // ============================================================
118
+ // Matrix utilities for least squares adjustment
119
+ // ============================================================
120
+
121
+ type Matrix = number[][]
122
+
123
+ const mat = {
124
+ zeros: (r: number, c: number): Matrix => Array.from({ length: r }, () => Array(c).fill(0) as number[]),
125
+
126
+ transpose: (a: Matrix): Matrix => a[0]!.map((_, j) => a.map((row) => row[j]!)),
127
+
128
+ mul: (a: Matrix, b: Matrix): Matrix =>
129
+ a.map((row) => b[0]!.map((_, j) => row.reduce((sum, val, k) => sum + val * b[k]![j]!, 0))),
130
+
131
+ mulVec: (a: Matrix, v: number[]): number[] => a.map((row) => row.reduce((sum, val, k) => sum + val * v[k]!, 0)),
132
+
133
+ invert: (src: Matrix): Matrix | null => {
134
+ const n = src.length
135
+ const aug = src.map((row, i) => [...row, ...Array.from({ length: n }, (_, j) => (i === j ? 1 : 0))])
136
+ for (let col = 0; col < n; col++) {
137
+ let pivotRow = col
138
+ for (let row = col + 1; row < n; row++) {
139
+ if (Math.abs(aug[row]![col]!) > Math.abs(aug[pivotRow]![col]!)) pivotRow = row
140
+ }
141
+ if (Math.abs(aug[pivotRow]![col]!) < 1e-15) return null
142
+ ;[aug[col], aug[pivotRow]] = [aug[pivotRow]!, aug[col]!]
143
+ const pivot = aug[col]![col]!
144
+ for (let j = col; j < 2 * n; j++) aug[col]![j]! /= pivot
145
+ for (let row = 0; row < n; row++) {
146
+ if (row === col) continue
147
+ const factor = aug[row]![col]!
148
+ for (let j = col; j < 2 * n; j++) aug[row]![j]! -= factor * aug[col]![j]!
149
+ }
150
+ }
151
+ return aug.map((row) => row.slice(n))
152
+ },
153
+ }
154
+
155
+ // ============================================================
156
+ // Leveling network least squares adjustment
157
+ // ============================================================
158
+
159
+ export const leveling_adjustment = tool({
160
+ description:
161
+ "水准网严密平差(最小二乘法)。输入已知基准点高程和观测的高差数据,返回平差后高程、残差、单位权中误差及各点精度评定。data_analyst 在处理完闭合差校核后,需要严密计算时必须调用此工具。",
162
+ args: {
163
+ benchmarks: tool.schema
164
+ .array(
165
+ tool.schema.object({
166
+ id: tool.schema.string().describe("基准点编号"),
167
+ height: tool.schema.number().describe("已知高程(m)"),
168
+ }),
169
+ )
170
+ .min(1)
171
+ .describe("已知高程的基准点列表(至少1个)"),
172
+ observations: tool.schema
173
+ .array(
174
+ tool.schema.object({
175
+ from: tool.schema.string().describe("后视点编号"),
176
+ to: tool.schema.string().describe("前视点编号"),
177
+ heightDiff: tool.schema.number().describe("观测高差(m),from→to方向为正"),
178
+ routeLength: tool.schema.number().positive().describe("该测段路线长度(km)"),
179
+ }),
180
+ )
181
+ .min(1)
182
+ .describe("所有观测高差数据"),
183
+ order: tool.schema
184
+ .enum(["1st", "2nd", "3rd", "4th", "city-2nd"])
185
+ .default("4th")
186
+ .describe("测量等级,用于精度评定对比"),
187
+ },
188
+ async execute(args) {
189
+ const knownMap = new Map(args.benchmarks.map((b) => [b.id, b.height]))
190
+ const unknownIds = [...new Set(args.observations.flatMap((o) => [o.from, o.to]).filter((id) => !knownMap.has(id)))]
191
+ const u = unknownIds.length
192
+ const n = args.observations.length
193
+
194
+ if (u === 0) return JSON.stringify({ error: "所有点均为已知点,无需平差。" })
195
+ if (n < u)
196
+ return JSON.stringify({
197
+ error: `观测数 ${n} 少于未知数 ${u},无法进行平差。需要至少 ${u} 个观测值。`,
198
+ })
199
+
200
+ const idxOf = (id: string) => unknownIds.indexOf(id)
201
+
202
+ // Build coefficient matrix A, weight matrix P, observation vector L
203
+ const A = mat.zeros(n, u)
204
+ const P = mat.zeros(n, n)
205
+ const L: number[] = []
206
+
207
+ for (let i = 0; i < n; i++) {
208
+ const obs = args.observations[i]!
209
+ const fromIdx = idxOf(obs.from)
210
+ const toIdx = idxOf(obs.to)
211
+
212
+ // A matrix: h_to - h_from = heightDiff
213
+ if (fromIdx >= 0) A[i]![fromIdx] = -1
214
+ if (toIdx >= 0) A[i]![toIdx] = 1
215
+
216
+ // Weight = 1/routeLength (proportional to inverse of distance)
217
+ P[i]![i] = 1 / obs.routeLength
218
+
219
+ // L = observed - computed from known values
220
+ const fromH = knownMap.get(obs.from) ?? 0
221
+ const toH = knownMap.get(obs.to) ?? 0
222
+ L.push(obs.heightDiff - (toH - fromH))
223
+ }
224
+
225
+ // Normal equation: N = A^T P A, b = A^T P L
226
+ const AT = mat.transpose(A)
227
+ const ATP = mat.mul(AT, P)
228
+ const N = mat.mul(ATP, A)
229
+ const b = mat.mulVec(ATP, L)
230
+
231
+ const Qxx = mat.invert(N)
232
+ if (!Qxx) return JSON.stringify({ error: "法方程系数矩阵奇异,无法求解。请检查网形是否连通。" })
233
+
234
+ // Solve: X = Qxx * b
235
+ const X = mat.mulVec(Qxx, b)
236
+
237
+ // Residuals: V = A*X - L
238
+ const AX = mat.mulVec(A, X)
239
+ const V = AX.map((v, i) => v - L[i]!)
240
+
241
+ // Unit weight RMSE: σ₀ = sqrt(V^T P V / (n - u))
242
+ const VTPV = V.reduce((sum, v, i) => sum + v * P[i]![i]! * v, 0)
243
+ const redundancy = n - u
244
+ const sigma0 = redundancy > 0 ? Math.sqrt(VTPV / redundancy) : 0
245
+
246
+ // Point height RMSE: σ_i = σ₀ * sqrt(Q_ii)
247
+ const adjusted = unknownIds.map((id, i) => {
248
+ const approxH = knownMap.get(id) ?? 0
249
+ const correction = X[i]!
250
+ const height = approxH + correction
251
+ const rmse = sigma0 * Math.sqrt(Math.abs(Qxx[i]![i]!))
252
+ return {
253
+ point_id: id,
254
+ adjusted_height_m: Number(height.toFixed(4)),
255
+ correction_mm: Number((correction * 1000).toFixed(3)),
256
+ rmse_mm: Number((rmse * 1000).toFixed(3)),
257
+ }
258
+ })
259
+
260
+ const residuals = args.observations.map((obs, i) => ({
261
+ from: obs.from,
262
+ to: obs.to,
263
+ observed_mm: Number((obs.heightDiff * 1000).toFixed(3)),
264
+ residual_mm: Number((V[i]! * 1000).toFixed(3)),
265
+ }))
266
+
267
+ const spec = LEVELING_LIMITS[args.order]!
268
+ const maxRmse = Math.max(...adjusted.map((a) => a.rmse_mm))
269
+
270
+ return JSON.stringify({
271
+ method: "最小二乘法严密平差",
272
+ known_points: args.benchmarks.length,
273
+ unknown_points: u,
274
+ observations: n,
275
+ redundancy,
276
+ unit_weight_rmse_mm: Number((sigma0 * 1000).toFixed(3)),
277
+ order_desc: spec.desc,
278
+ max_point_rmse_mm: maxRmse,
279
+ adjusted_heights: adjusted,
280
+ residuals,
281
+ assessment:
282
+ sigma0 * 1000 < spec.k
283
+ ? `✅ 单位权中误差 ${(sigma0 * 1000).toFixed(3)}mm < ${spec.k}mm(${spec.desc}限差系数),精度合格`
284
+ : `⚠️ 单位权中误差 ${(sigma0 * 1000).toFixed(3)}mm ≥ ${spec.k}mm(${spec.desc}限差系数),建议检查观测质量`,
285
+ })
286
+ },
287
+ })
288
+
289
+ // ============================================================
290
+ // Traverse network coordinate adjustment
291
+ // ============================================================
292
+
293
+ const deg2rad = (d: number) => (d * Math.PI) / 180
294
+
295
+ export const traverse_adjustment = tool({
296
+ description:
297
+ "附合导线/闭合导线坐标平差计算。输入起始点坐标、起始方位角、各站观测角和边长,返回平差后坐标、闭合差分析及各点精度。data_analyst 在处理导线测量数据时必须调用此工具。",
298
+ args: {
299
+ startPoint: tool.schema
300
+ .object({
301
+ id: tool.schema.string().describe("起始点编号"),
302
+ x: tool.schema.number().describe("起始点X坐标(东方向/m)"),
303
+ y: tool.schema.number().describe("起始点Y坐标(北方向/m)"),
304
+ })
305
+ .describe("起始已知点"),
306
+ endPoint: tool.schema
307
+ .object({
308
+ id: tool.schema.string().describe("终止点编号"),
309
+ x: tool.schema.number().describe("终止点X坐标(东方向/m)"),
310
+ y: tool.schema.number().describe("终止点Y坐标(北方向/m)"),
311
+ })
312
+ .describe("终止已知点(附合导线需要;闭合导线与起始点相同)"),
313
+ startAzimuth: tool.schema.number().describe("起始边方位角(度,十进制)"),
314
+ endAzimuth: tool.schema.number().describe("终止边方位角(度,十进制);闭合导线传起始方位角"),
315
+ stations: tool.schema
316
+ .array(
317
+ tool.schema.object({
318
+ id: tool.schema.string().describe("转折点编号"),
319
+ angle: tool.schema.number().describe("观测的左角/转折角(度,十进制)"),
320
+ distance: tool.schema.number().positive().describe("该站到下一站的边长(m)"),
321
+ }),
322
+ )
323
+ .min(1)
324
+ .describe("各导线测站观测数据(按测量顺序排列)"),
325
+ instrument: tool.schema.enum(["DJ1", "DJ2", "DJ6"]).default("DJ2").describe("经纬仪等级"),
326
+ },
327
+ async execute(args) {
328
+ const n = args.stations.length
329
+ const angSpec = TRAVERSE_ANGULAR_LIMITS[args.instrument]!
330
+
331
+ // Step 1: Angular closure
332
+ const sumAngles = args.stations.reduce((s, st) => s + st.angle, 0)
333
+ const theoreticalSum = (((args.endAzimuth - args.startAzimuth + 180 * n) % 360) + 360) % 360
334
+ const angularClosure = sumAngles - theoreticalSum
335
+ const normalized =
336
+ angularClosure > 180 ? angularClosure - 360 : angularClosure < -180 ? angularClosure + 360 : angularClosure
337
+ const closureSec = normalized * 3600
338
+ const angLimit = angSpec.k * Math.sqrt(n)
339
+
340
+ if (Math.abs(closureSec) > angLimit)
341
+ return JSON.stringify({
342
+ error: `角度闭合差 ${closureSec.toFixed(1)}″ 超出限差 ±${angLimit.toFixed(1)}″(${angSpec.desc}),请先返工重测角度。`,
343
+ angular_closure_arcsec: Number(closureSec.toFixed(1)),
344
+ angular_limit_arcsec: Number(angLimit.toFixed(1)),
345
+ })
346
+
347
+ // Step 2: Distribute angular error equally
348
+ const corr = -normalized / n
349
+ const azimuths: number[] = []
350
+ let az = args.startAzimuth
351
+ for (const st of args.stations) {
352
+ az = (((az + st.angle + corr + 180) % 360) + 360) % 360
353
+ azimuths.push(az)
354
+ }
355
+
356
+ // Step 3: Compute provisional coordinates
357
+ const totalDist = args.stations.reduce((s, st) => s + st.distance, 0)
358
+ const dxArr = args.stations.map((st, i) => st.distance * Math.sin(deg2rad(azimuths[i]!)))
359
+ const dyArr = args.stations.map((st, i) => st.distance * Math.cos(deg2rad(azimuths[i]!)))
360
+
361
+ const sumDx = dxArr.reduce((a, b) => a + b, 0)
362
+ const sumDy = dyArr.reduce((a, b) => a + b, 0)
363
+ const fx = sumDx - (args.endPoint.x - args.startPoint.x)
364
+ const fy = sumDy - (args.endPoint.y - args.startPoint.y)
365
+ const closureDist = Math.sqrt(fx * fx + fy * fy)
366
+ const relClosure = totalDist > 0 ? totalDist / closureDist : Infinity
367
+
368
+ // Step 4: Distribute coordinate closure proportionally
369
+ const coords: Array<{ id: string; x: number; y: number }> = []
370
+ let cumDist = 0
371
+
372
+ for (let i = 0; i < n; i++) {
373
+ cumDist += args.stations[i]!.distance
374
+ const ratio = cumDist / totalDist
375
+ const cx = args.startPoint.x + dxArr.slice(0, i + 1).reduce((a, b) => a + b, 0) - fx * ratio
376
+ const cy = args.startPoint.y + dyArr.slice(0, i + 1).reduce((a, b) => a + b, 0) - fy * ratio
377
+ coords.push({ id: args.stations[i]!.id, x: Number(cx.toFixed(4)), y: Number(cy.toFixed(4)) })
378
+ }
379
+
380
+ const pointRmse = closureDist / Math.sqrt(3 * n)
381
+
382
+ return JSON.stringify({
383
+ method: "附合导线简易平差(角度等权分配,坐标按边长比例分配)",
384
+ station_count: n,
385
+ total_distance_m: Number(totalDist.toFixed(3)),
386
+ angular_closure: {
387
+ measured_arcsec: Number(closureSec.toFixed(1)),
388
+ limit_arcsec: Number(angLimit.toFixed(1)),
389
+ correction_per_station_arcsec: Number((corr * 3600).toFixed(2)),
390
+ is_passed: true,
391
+ },
392
+ coordinate_closure: {
393
+ fx_m: Number(fx.toFixed(4)),
394
+ fy_m: Number(fy.toFixed(4)),
395
+ closure_distance_m: Number(closureDist.toFixed(4)),
396
+ relative_closure: `1/${Math.round(relClosure)}`,
397
+ assessment:
398
+ relClosure >= 10000
399
+ ? "✅ 优秀(全长相对闭合差 < 1/10000)"
400
+ : relClosure >= 4000
401
+ ? "✅ 良好(全长相对闭合差 < 1/4000)"
402
+ : relClosure >= 2000
403
+ ? "⚠️ 一般(全长相对闭合差 < 1/2000),建议复查"
404
+ : "❌ 不合格,需返工重测",
405
+ },
406
+ adjusted_coordinates: coords,
407
+ azimuths_deg: azimuths.map((a, i) => ({
408
+ from: i === 0 ? args.startPoint.id : args.stations[i - 1]!.id,
409
+ to: args.stations[i]!.id,
410
+ azimuth: Number(a.toFixed(6)),
411
+ })),
412
+ point_rmse_mm: Number((pointRmse * 1000).toFixed(2)),
413
+ })
414
+ },
415
+ })
@@ -0,0 +1,209 @@
1
+ /// <reference path="../env.d.ts" />
2
+ import { tool } from "nb-railwise/tool"
3
+
4
+ export const water_level_analysis = tool({
5
+ description:
6
+ "基坑地下水位监测数据分析。根据水位观测井的水位数据序列,计算水位变化量、变化速率,判断降水效果和回灌影响。基坑自动化监测中水位监控的核心工具。data_analyst 处理水位数据时必须调用此工具。",
7
+ args: {
8
+ wellId: tool.schema.string().describe("观测井编号,如 SW-01"),
9
+ wellType: tool.schema
10
+ .enum(["pumping", "observation", "recharge"])
11
+ .describe("井类型:pumping=降水井, observation=观测井, recharge=回灌井"),
12
+ groundElevation: tool.schema.number().describe("井口地面标高(m)"),
13
+ initialLevel: tool.schema.number().describe("初始水位标高(m)或初始埋深(m)"),
14
+ levelType: tool.schema
15
+ .enum(["elevation", "depth"])
16
+ .default("elevation")
17
+ .describe("水位值类型:elevation=绝对标高, depth=距地面埋深"),
18
+ records: tool.schema
19
+ .array(
20
+ tool.schema.object({
21
+ date: tool.schema.string().describe("观测日期 YYYY-MM-DD 或 YYYY-MM-DD HH:mm"),
22
+ level: tool.schema.number().describe("水位值(标高m或埋深m,与levelType一致)"),
23
+ }),
24
+ )
25
+ .min(1)
26
+ .describe("水位观测数据"),
27
+ targetLevel: tool.schema.number().optional().describe("目标降水水位标高(m)或目标埋深(m)"),
28
+ alertRise: tool.schema.number().positive().optional().describe("水位回升报警值(m),超过此值需预警"),
29
+ excavationBottom: tool.schema.number().optional().describe("基坑底标高(m),用于计算水头差"),
30
+ },
31
+ async execute(args) {
32
+ const toElevation = (v: number) => (args.levelType === "elevation" ? v : args.groundElevation - v)
33
+
34
+ const initElev = toElevation(args.initialLevel)
35
+
36
+ const analyzed = args.records.map((r, i) => {
37
+ const elev = toElevation(r.level)
38
+ const depth = args.groundElevation - elev
39
+ const change = elev - initElev
40
+ const headAboveExcavation = args.excavationBottom !== undefined ? elev - args.excavationBottom : null
41
+
42
+ let status = "🟢 正常"
43
+ if (args.alertRise && change > args.alertRise) {
44
+ status = "🔴 水位回升超限"
45
+ } else if (args.targetLevel !== undefined) {
46
+ const targetElev = toElevation(args.targetLevel)
47
+ if (elev > targetElev + 0.5) status = "🟡 未达目标"
48
+ else if (elev <= targetElev) status = "🟢 已达目标"
49
+ }
50
+
51
+ return {
52
+ date: r.date,
53
+ elevation_m: Number(elev.toFixed(3)),
54
+ depth_m: Number(depth.toFixed(3)),
55
+ change_from_initial_m: Number(change.toFixed(3)),
56
+ head_above_excavation_m: headAboveExcavation !== null ? Number(headAboveExcavation.toFixed(3)) : null,
57
+ status,
58
+ }
59
+ })
60
+
61
+ const rates: Array<{ period: string; rate_m_per_day: number }> = []
62
+ for (let i = 1; i < analyzed.length; i++) {
63
+ const dt = (new Date(args.records[i]!.date).getTime() - new Date(args.records[i - 1]!.date).getTime()) / 86400000
64
+ if (dt > 0) {
65
+ rates.push({
66
+ period: `${args.records[i - 1]!.date} → ${args.records[i]!.date}`,
67
+ rate_m_per_day: Number(((analyzed[i]!.elevation_m - analyzed[i - 1]!.elevation_m) / dt).toFixed(4)),
68
+ })
69
+ }
70
+ }
71
+
72
+ const latest = analyzed[analyzed.length - 1]!
73
+ const lowest = analyzed.reduce((min, a) => (a.elevation_m < min.elevation_m ? a : min), analyzed[0]!)
74
+ const highest = analyzed.reduce((max, a) => (a.elevation_m > max.elevation_m ? a : max), analyzed[0]!)
75
+ const amplitude = highest.elevation_m - lowest.elevation_m
76
+
77
+ let dewateringAssessment = ""
78
+ if (args.targetLevel !== undefined) {
79
+ const targetElev = toElevation(args.targetLevel)
80
+ if (latest.elevation_m <= targetElev) {
81
+ dewateringAssessment = "✅ 降水达标,水位已降至目标水位以下"
82
+ } else {
83
+ const gap = latest.elevation_m - targetElev
84
+ dewateringAssessment = `⚠️ 降水未达标,当前水位高于目标 ${gap.toFixed(3)}m,需加强降水`
85
+ }
86
+ }
87
+
88
+ let safetyAssessment = ""
89
+ if (args.excavationBottom !== undefined && latest.head_above_excavation_m !== null) {
90
+ if (latest.head_above_excavation_m > 0) {
91
+ safetyAssessment = `⚠️ 水位高于基坑底 ${latest.head_above_excavation_m.toFixed(3)}m,存在突涌风险`
92
+ } else {
93
+ safetyAssessment = `✅ 水位低于基坑底 ${Math.abs(latest.head_above_excavation_m).toFixed(3)}m`
94
+ }
95
+ }
96
+
97
+ return JSON.stringify({
98
+ well_id: args.wellId,
99
+ well_type: args.wellType === "pumping" ? "降水井" : args.wellType === "observation" ? "观测井" : "回灌井",
100
+ ground_elevation_m: args.groundElevation,
101
+ initial_elevation_m: Number(initElev.toFixed(3)),
102
+ latest: {
103
+ date: latest.date,
104
+ elevation_m: latest.elevation_m,
105
+ depth_m: latest.depth_m,
106
+ change_m: latest.change_from_initial_m,
107
+ },
108
+ range: {
109
+ lowest_m: lowest.elevation_m,
110
+ highest_m: highest.elevation_m,
111
+ amplitude_m: Number(amplitude.toFixed(3)),
112
+ },
113
+ records: analyzed,
114
+ rates,
115
+ dewatering_assessment: dewateringAssessment || undefined,
116
+ safety_assessment: safetyAssessment || undefined,
117
+ message: `✅ ${args.wellId} 水位分析:当前标高 ${latest.elevation_m}m(埋深 ${latest.depth_m}m),较初始${latest.change_from_initial_m > 0 ? "上升" : "下降"} ${Math.abs(latest.change_from_initial_m).toFixed(3)}m`,
118
+ })
119
+ },
120
+ })
121
+
122
+ export const water_level_contour = tool({
123
+ description:
124
+ "多井水位等值线数据生成。根据多个观测井的坐标和水位数据,计算水位梯度和流向,为绘制等水位线图提供数据。用于基坑降水效果评估。",
125
+ args: {
126
+ wells: tool.schema
127
+ .array(
128
+ tool.schema.object({
129
+ id: tool.schema.string().describe("井编号"),
130
+ x: tool.schema.number().describe("X坐标(m)"),
131
+ y: tool.schema.number().describe("Y坐标(m)"),
132
+ elevation: tool.schema.number().describe("当前水位标高(m)"),
133
+ }),
134
+ )
135
+ .min(3)
136
+ .describe("各井位置和水位(至少3口井)"),
137
+ excavationCenter: tool.schema
138
+ .object({
139
+ x: tool.schema.number().describe("基坑中心X"),
140
+ y: tool.schema.number().describe("基坑中心Y"),
141
+ })
142
+ .optional()
143
+ .describe("基坑中心坐标,用于判断降水漏斗形态"),
144
+ },
145
+ async execute(args) {
146
+ const n = args.wells.length
147
+ const avgElev = args.wells.reduce((s, w) => s + w.elevation, 0) / n
148
+ const maxWell = args.wells.reduce((max, w) => (w.elevation > max.elevation ? w : max), args.wells[0]!)
149
+ const minWell = args.wells.reduce((min, w) => (w.elevation < min.elevation ? w : min), args.wells[0]!)
150
+
151
+ const gradients: Array<{
152
+ from: string
153
+ to: string
154
+ gradient: number
155
+ distance_m: number
156
+ direction_deg: number
157
+ }> = []
158
+
159
+ for (let i = 0; i < n; i++) {
160
+ for (let j = i + 1; j < n; j++) {
161
+ const a = args.wells[i]!
162
+ const b = args.wells[j]!
163
+ const dist = Math.sqrt((b.x - a.x) ** 2 + (b.y - a.y) ** 2)
164
+ if (dist < 0.1) continue
165
+ const grad = Math.abs(b.elevation - a.elevation) / dist
166
+ const dir = (Math.atan2(b.x - a.x, b.y - a.y) * 180) / Math.PI
167
+ gradients.push({
168
+ from: a.id,
169
+ to: b.id,
170
+ gradient: Number(grad.toFixed(6)),
171
+ distance_m: Number(dist.toFixed(2)),
172
+ direction_deg: Number(((dir + 360) % 360).toFixed(1)),
173
+ })
174
+ }
175
+ }
176
+
177
+ const avgGradient = gradients.length > 0 ? gradients.reduce((s, g) => s + g.gradient, 0) / gradients.length : 0
178
+
179
+ let funnelAssessment = ""
180
+ if (args.excavationCenter) {
181
+ const cx = args.excavationCenter.x
182
+ const cy = args.excavationCenter.y
183
+ const sorted = args.wells
184
+ .map((w) => ({ id: w.id, elev: w.elevation, dist: Math.sqrt((w.x - cx) ** 2 + (w.y - cy) ** 2) }))
185
+ .sort((a, b) => a.dist - b.dist)
186
+
187
+ const innerAvg = sorted.slice(0, Math.ceil(n / 2)).reduce((s, w) => s + w.elev, 0) / Math.ceil(n / 2)
188
+ const outerAvg = sorted.slice(Math.ceil(n / 2)).reduce((s, w) => s + w.elev, 0) / (n - Math.ceil(n / 2))
189
+
190
+ if (innerAvg < outerAvg) {
191
+ funnelAssessment = `✅ 降水漏斗形态正常:内侧平均水位 ${innerAvg.toFixed(3)}m < 外侧 ${outerAvg.toFixed(3)}m`
192
+ } else {
193
+ funnelAssessment = `⚠️ 降水漏斗异常:内侧平均水位 ${innerAvg.toFixed(3)}m ≥ 外侧 ${outerAvg.toFixed(3)}m,降水效果不佳`
194
+ }
195
+ }
196
+
197
+ return JSON.stringify({
198
+ well_count: n,
199
+ average_elevation_m: Number(avgElev.toFixed(3)),
200
+ max_well: { id: maxWell.id, elevation_m: maxWell.elevation },
201
+ min_well: { id: minWell.id, elevation_m: minWell.elevation },
202
+ level_difference_m: Number((maxWell.elevation - minWell.elevation).toFixed(3)),
203
+ average_gradient: Number(avgGradient.toFixed(6)),
204
+ gradients,
205
+ funnel_assessment: funnelAssessment || undefined,
206
+ message: `✅ ${n}口井水位分析:水位差 ${(maxWell.elevation - minWell.elevation).toFixed(3)}m,平均梯度 ${avgGradient.toFixed(6)}`,
207
+ })
208
+ },
209
+ })