@geotechcli/core 0.2.0
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/dist/agents/brain.d.ts +39 -0
- package/dist/agents/brain.d.ts.map +1 -0
- package/dist/agents/brain.js +339 -0
- package/dist/agents/brain.js.map +1 -0
- package/dist/agents/bridge-tools.d.ts +2 -0
- package/dist/agents/bridge-tools.d.ts.map +1 -0
- package/dist/agents/bridge-tools.js +170 -0
- package/dist/agents/bridge-tools.js.map +1 -0
- package/dist/agents/data-tools.d.ts +2 -0
- package/dist/agents/data-tools.d.ts.map +1 -0
- package/dist/agents/data-tools.js +309 -0
- package/dist/agents/data-tools.js.map +1 -0
- package/dist/agents/filesystem-tools.d.ts +2 -0
- package/dist/agents/filesystem-tools.d.ts.map +1 -0
- package/dist/agents/filesystem-tools.js +267 -0
- package/dist/agents/filesystem-tools.js.map +1 -0
- package/dist/agents/guardrails.d.ts +17 -0
- package/dist/agents/guardrails.d.ts.map +1 -0
- package/dist/agents/guardrails.js +260 -0
- package/dist/agents/guardrails.js.map +1 -0
- package/dist/agents/orchestrator.d.ts +9 -0
- package/dist/agents/orchestrator.d.ts.map +1 -0
- package/dist/agents/orchestrator.js +136 -0
- package/dist/agents/orchestrator.js.map +1 -0
- package/dist/agents/safety.d.ts +9 -0
- package/dist/agents/safety.d.ts.map +1 -0
- package/dist/agents/safety.js +40 -0
- package/dist/agents/safety.js.map +1 -0
- package/dist/agents/sandbox.d.ts +34 -0
- package/dist/agents/sandbox.d.ts.map +1 -0
- package/dist/agents/sandbox.js +235 -0
- package/dist/agents/sandbox.js.map +1 -0
- package/dist/agents/swarm.d.ts +25 -0
- package/dist/agents/swarm.d.ts.map +1 -0
- package/dist/agents/swarm.js +434 -0
- package/dist/agents/swarm.js.map +1 -0
- package/dist/agents/tools.d.ts +37 -0
- package/dist/agents/tools.d.ts.map +1 -0
- package/dist/agents/tools.js +451 -0
- package/dist/agents/tools.js.map +1 -0
- package/dist/bridge/index.d.ts +52 -0
- package/dist/bridge/index.d.ts.map +1 -0
- package/dist/bridge/index.js +195 -0
- package/dist/bridge/index.js.map +1 -0
- package/dist/config/index.d.ts +106 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +217 -0
- package/dist/config/index.js.map +1 -0
- package/dist/db/index.d.ts +4 -0
- package/dist/db/index.d.ts.map +1 -0
- package/dist/db/index.js +4 -0
- package/dist/db/index.js.map +1 -0
- package/dist/db/redis.d.ts +14 -0
- package/dist/db/redis.d.ts.map +1 -0
- package/dist/db/redis.js +204 -0
- package/dist/db/redis.js.map +1 -0
- package/dist/db/supabase.d.ts +57 -0
- package/dist/db/supabase.d.ts.map +1 -0
- package/dist/db/supabase.js +156 -0
- package/dist/db/supabase.js.map +1 -0
- package/dist/db/users.d.ts +50 -0
- package/dist/db/users.d.ts.map +1 -0
- package/dist/db/users.js +132 -0
- package/dist/db/users.js.map +1 -0
- package/dist/export/index.d.ts +51 -0
- package/dist/export/index.d.ts.map +1 -0
- package/dist/export/index.js +126 -0
- package/dist/export/index.js.map +1 -0
- package/dist/geo/bearing-capacity.d.ts +60 -0
- package/dist/geo/bearing-capacity.d.ts.map +1 -0
- package/dist/geo/bearing-capacity.js +195 -0
- package/dist/geo/bearing-capacity.js.map +1 -0
- package/dist/geo/classification.d.ts +107 -0
- package/dist/geo/classification.d.ts.map +1 -0
- package/dist/geo/classification.js +261 -0
- package/dist/geo/classification.js.map +1 -0
- package/dist/geo/index.d.ts +9 -0
- package/dist/geo/index.d.ts.map +1 -0
- package/dist/geo/index.js +9 -0
- package/dist/geo/index.js.map +1 -0
- package/dist/geo/lateral-earth-pressure.d.ts +75 -0
- package/dist/geo/lateral-earth-pressure.d.ts.map +1 -0
- package/dist/geo/lateral-earth-pressure.js +219 -0
- package/dist/geo/lateral-earth-pressure.js.map +1 -0
- package/dist/geo/liquefaction.d.ts +65 -0
- package/dist/geo/liquefaction.d.ts.map +1 -0
- package/dist/geo/liquefaction.js +163 -0
- package/dist/geo/liquefaction.js.map +1 -0
- package/dist/geo/pile-capacity.d.ts +91 -0
- package/dist/geo/pile-capacity.d.ts.map +1 -0
- package/dist/geo/pile-capacity.js +233 -0
- package/dist/geo/pile-capacity.js.map +1 -0
- package/dist/geo/settlement.d.ts +119 -0
- package/dist/geo/settlement.d.ts.map +1 -0
- package/dist/geo/settlement.js +184 -0
- package/dist/geo/settlement.js.map +1 -0
- package/dist/geo/slope-stability.d.ts +82 -0
- package/dist/geo/slope-stability.d.ts.map +1 -0
- package/dist/geo/slope-stability.js +214 -0
- package/dist/geo/slope-stability.js.map +1 -0
- package/dist/geo/tunnel/index.d.ts +2 -0
- package/dist/geo/tunnel/index.d.ts.map +1 -0
- package/dist/geo/tunnel/index.js +2 -0
- package/dist/geo/tunnel/index.js.map +1 -0
- package/dist/geo/tunnel/tbm.d.ts +135 -0
- package/dist/geo/tunnel/tbm.d.ts.map +1 -0
- package/dist/geo/tunnel/tbm.js +268 -0
- package/dist/geo/tunnel/tbm.js.map +1 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +33 -0
- package/dist/index.js.map +1 -0
- package/dist/ingest/ags.d.ts +42 -0
- package/dist/ingest/ags.d.ts.map +1 -0
- package/dist/ingest/ags.js +133 -0
- package/dist/ingest/ags.js.map +1 -0
- package/dist/ingest/cpt.d.ts +47 -0
- package/dist/ingest/cpt.d.ts.map +1 -0
- package/dist/ingest/cpt.js +112 -0
- package/dist/ingest/cpt.js.map +1 -0
- package/dist/ingest/index.d.ts +3 -0
- package/dist/ingest/index.d.ts.map +1 -0
- package/dist/ingest/index.js +3 -0
- package/dist/ingest/index.js.map +1 -0
- package/dist/llm/index.d.ts +5 -0
- package/dist/llm/index.d.ts.map +1 -0
- package/dist/llm/index.js +4 -0
- package/dist/llm/index.js.map +1 -0
- package/dist/llm/middleware/metering.d.ts +55 -0
- package/dist/llm/middleware/metering.d.ts.map +1 -0
- package/dist/llm/middleware/metering.js +191 -0
- package/dist/llm/middleware/metering.js.map +1 -0
- package/dist/llm/middleware/persistent-usage.d.ts +7 -0
- package/dist/llm/middleware/persistent-usage.d.ts.map +1 -0
- package/dist/llm/middleware/persistent-usage.js +108 -0
- package/dist/llm/middleware/persistent-usage.js.map +1 -0
- package/dist/llm/middleware/retry.d.ts +7 -0
- package/dist/llm/middleware/retry.d.ts.map +1 -0
- package/dist/llm/middleware/retry.js +29 -0
- package/dist/llm/middleware/retry.js.map +1 -0
- package/dist/llm/providers/anthropic.d.ts +10 -0
- package/dist/llm/providers/anthropic.d.ts.map +1 -0
- package/dist/llm/providers/anthropic.js +107 -0
- package/dist/llm/providers/anthropic.js.map +1 -0
- package/dist/llm/providers/hosted-beta.d.ts +10 -0
- package/dist/llm/providers/hosted-beta.d.ts.map +1 -0
- package/dist/llm/providers/hosted-beta.js +106 -0
- package/dist/llm/providers/hosted-beta.js.map +1 -0
- package/dist/llm/providers/huggingface.d.ts +37 -0
- package/dist/llm/providers/huggingface.d.ts.map +1 -0
- package/dist/llm/providers/huggingface.js +133 -0
- package/dist/llm/providers/huggingface.js.map +1 -0
- package/dist/llm/providers/openai-compatible.d.ts +27 -0
- package/dist/llm/providers/openai-compatible.d.ts.map +1 -0
- package/dist/llm/providers/openai-compatible.js +99 -0
- package/dist/llm/providers/openai-compatible.js.map +1 -0
- package/dist/llm/providers/zhipu.d.ts +10 -0
- package/dist/llm/providers/zhipu.d.ts.map +1 -0
- package/dist/llm/providers/zhipu.js +81 -0
- package/dist/llm/providers/zhipu.js.map +1 -0
- package/dist/llm/router.d.ts +35 -0
- package/dist/llm/router.d.ts.map +1 -0
- package/dist/llm/router.js +109 -0
- package/dist/llm/router.js.map +1 -0
- package/dist/llm/types.d.ts +63 -0
- package/dist/llm/types.d.ts.map +1 -0
- package/dist/llm/types.js +38 -0
- package/dist/llm/types.js.map +1 -0
- package/dist/meta/index.d.ts +12 -0
- package/dist/meta/index.d.ts.map +1 -0
- package/dist/meta/index.js +8 -0
- package/dist/meta/index.js.map +1 -0
- package/dist/meta/metadata.json +46 -0
- package/dist/report/index.d.ts +20 -0
- package/dist/report/index.d.ts.map +1 -0
- package/dist/report/index.js +58 -0
- package/dist/report/index.js.map +1 -0
- package/dist/standards/index.d.ts +23 -0
- package/dist/standards/index.d.ts.map +1 -0
- package/dist/standards/index.js +89 -0
- package/dist/standards/index.js.map +1 -0
- package/dist/storage/index.d.ts +114 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +465 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/vision/index.d.ts +80 -0
- package/dist/vision/index.d.ts.map +1 -0
- package/dist/vision/index.js +298 -0
- package/dist/vision/index.js.map +1 -0
- package/dist/vision/parse.d.ts +20 -0
- package/dist/vision/parse.d.ts.map +1 -0
- package/dist/vision/parse.js +75 -0
- package/dist/vision/parse.js.map +1 -0
- package/package.json +55 -0
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
import { generateVision, generateText } from '../llm/router.js';
|
|
2
|
+
import { classifyRMR89 } from '../geo/classification.js';
|
|
3
|
+
import { clampConfidence, createParseSafety, deriveParseStatus, normalizeWarnings, parseJsonObject, readNumber, readString, } from './parse.js';
|
|
4
|
+
const VALID_JOINT_CONDITIONS = [
|
|
5
|
+
'very_good',
|
|
6
|
+
'good',
|
|
7
|
+
'fair',
|
|
8
|
+
'poor',
|
|
9
|
+
'very_poor',
|
|
10
|
+
];
|
|
11
|
+
const VALID_GROUNDWATER_CONDITIONS = [
|
|
12
|
+
'dry',
|
|
13
|
+
'damp',
|
|
14
|
+
'wet',
|
|
15
|
+
'dripping',
|
|
16
|
+
'flowing',
|
|
17
|
+
];
|
|
18
|
+
function asEnumValue(value, allowed, warnings, key) {
|
|
19
|
+
if (value && allowed.includes(value)) {
|
|
20
|
+
return value;
|
|
21
|
+
}
|
|
22
|
+
warnings.push(`Field "${key}" must be one of: ${allowed.join(', ')}.`);
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
function combineWarnings(base, extra) {
|
|
26
|
+
return [...new Set([...base, ...extra])];
|
|
27
|
+
}
|
|
28
|
+
export async function analyzeCoreBox(imageBase64, mimeType, config) {
|
|
29
|
+
const prompt = `Analyze this rock core box image. You MUST respond with ONLY a JSON object (no markdown, no backticks, no explanation) with these exact fields:
|
|
30
|
+
{
|
|
31
|
+
"rqd": <number 0-100, Rock Quality Designation percentage>,
|
|
32
|
+
"fractureSpacing": "<string: very close/close/moderate/wide/very wide>",
|
|
33
|
+
"weatheringGrade": "<string: W1-Fresh/W2-Slightly/W3-Moderately/W4-Highly/W5-Completely/W6-Residual>",
|
|
34
|
+
"rockType": "<string: identified lithology>",
|
|
35
|
+
"coreRecovery": <number 0-100, percentage>,
|
|
36
|
+
"discontinuities": "<string: description of joint surfaces, infilling, roughness>",
|
|
37
|
+
"confidence": <number 0-100>,
|
|
38
|
+
"warnings": ["<warning>", "<warning>"]
|
|
39
|
+
}`;
|
|
40
|
+
const response = await generateVision(prompt, imageBase64, mimeType, config, {
|
|
41
|
+
systemPrompt: 'You are an expert engineering geologist performing core logging. Respond with JSON only.',
|
|
42
|
+
temperature: 0.1,
|
|
43
|
+
maxTokens: 900,
|
|
44
|
+
});
|
|
45
|
+
const parsed = parseJsonObject(response.text);
|
|
46
|
+
const warnings = [...parsed.warnings];
|
|
47
|
+
const rqd = readNumber(parsed.value, 'rqd', warnings);
|
|
48
|
+
const fractureSpacing = readString(parsed.value, 'fractureSpacing', warnings);
|
|
49
|
+
const weatheringGrade = readString(parsed.value, 'weatheringGrade', warnings);
|
|
50
|
+
const rockType = readString(parsed.value, 'rockType', warnings);
|
|
51
|
+
const coreRecovery = readNumber(parsed.value, 'coreRecovery', warnings);
|
|
52
|
+
const discontinuities = readString(parsed.value, 'discontinuities', warnings);
|
|
53
|
+
const confidence = clampConfidence(parsed.value?.confidence, parsed.baseStatus === 'parsed' ? 80 : 0);
|
|
54
|
+
const status = deriveParseStatus(parsed.baseStatus, [rqd, fractureSpacing, weatheringGrade, rockType, coreRecovery, discontinuities].filter((value) => value !== null).length, 6);
|
|
55
|
+
const safety = createParseSafety(status, confidence, combineWarnings(warnings, normalizeWarnings(parsed.value?.warnings)));
|
|
56
|
+
return {
|
|
57
|
+
...safety,
|
|
58
|
+
rqd,
|
|
59
|
+
fractureSpacing,
|
|
60
|
+
weatheringGrade,
|
|
61
|
+
rockType,
|
|
62
|
+
coreRecovery,
|
|
63
|
+
discontinuities,
|
|
64
|
+
rawAnalysis: response.text,
|
|
65
|
+
latencyMs: response.latencyMs,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
export async function classifyRMRFromImage(imageBase64, mimeType, config) {
|
|
69
|
+
const prompt = `Analyze this rock exposure / tunnel face / core box image for Rock Mass Rating input parameters. Respond with ONLY a JSON object (no markdown):
|
|
70
|
+
{
|
|
71
|
+
"estimatedUCS": <number in MPa, estimate from visual appearance>,
|
|
72
|
+
"estimatedRQD": <number 0-100>,
|
|
73
|
+
"estimatedSpacing": <number in meters, mean discontinuity spacing>,
|
|
74
|
+
"jointCondition": "<very_good|good|fair|poor|very_poor>",
|
|
75
|
+
"groundwaterCondition": "<dry|damp|wet|dripping|flowing>",
|
|
76
|
+
"confidence": <number 0-100>,
|
|
77
|
+
"warnings": ["<warning>", "<warning>"]
|
|
78
|
+
}`;
|
|
79
|
+
const response = await generateVision(prompt, imageBase64, mimeType, config, {
|
|
80
|
+
systemPrompt: 'You are an expert rock mechanics engineer performing field classification. Respond with JSON only.',
|
|
81
|
+
temperature: 0.1,
|
|
82
|
+
maxTokens: 700,
|
|
83
|
+
});
|
|
84
|
+
const parsed = parseJsonObject(response.text);
|
|
85
|
+
const warnings = [...parsed.warnings];
|
|
86
|
+
const estimatedUCS = readNumber(parsed.value, 'estimatedUCS', warnings);
|
|
87
|
+
const estimatedRQD = readNumber(parsed.value, 'estimatedRQD', warnings);
|
|
88
|
+
const estimatedSpacing = readNumber(parsed.value, 'estimatedSpacing', warnings);
|
|
89
|
+
const jointCondition = asEnumValue(readString(parsed.value, 'jointCondition', warnings), VALID_JOINT_CONDITIONS, warnings, 'jointCondition');
|
|
90
|
+
const groundwaterCondition = asEnumValue(readString(parsed.value, 'groundwaterCondition', warnings), VALID_GROUNDWATER_CONDITIONS, warnings, 'groundwaterCondition');
|
|
91
|
+
const confidence = clampConfidence(parsed.value?.confidence, parsed.baseStatus === 'parsed' ? 75 : 0);
|
|
92
|
+
const status = deriveParseStatus(parsed.baseStatus, [
|
|
93
|
+
estimatedUCS,
|
|
94
|
+
estimatedRQD,
|
|
95
|
+
estimatedSpacing,
|
|
96
|
+
jointCondition,
|
|
97
|
+
groundwaterCondition,
|
|
98
|
+
].filter((value) => value !== null).length, 5);
|
|
99
|
+
const safety = createParseSafety(status, confidence, combineWarnings(warnings, normalizeWarnings(parsed.value?.warnings)));
|
|
100
|
+
const visionExtraction = {
|
|
101
|
+
estimatedUCS,
|
|
102
|
+
estimatedRQD,
|
|
103
|
+
estimatedSpacing,
|
|
104
|
+
jointCondition,
|
|
105
|
+
groundwaterCondition,
|
|
106
|
+
};
|
|
107
|
+
let rmrResult = null;
|
|
108
|
+
if (safety.canAutoProceed &&
|
|
109
|
+
estimatedUCS !== null &&
|
|
110
|
+
estimatedRQD !== null &&
|
|
111
|
+
estimatedSpacing !== null &&
|
|
112
|
+
jointCondition !== null &&
|
|
113
|
+
groundwaterCondition !== null) {
|
|
114
|
+
const scored = classifyRMR89({
|
|
115
|
+
ucs: estimatedUCS,
|
|
116
|
+
rqd: estimatedRQD,
|
|
117
|
+
spacing: estimatedSpacing,
|
|
118
|
+
condition: jointCondition,
|
|
119
|
+
groundwater: groundwaterCondition,
|
|
120
|
+
orientationAdjustment: 0,
|
|
121
|
+
});
|
|
122
|
+
rmrResult = {
|
|
123
|
+
totalRating: scored.totalRating,
|
|
124
|
+
rockClass: scored.rockClass,
|
|
125
|
+
classNumber: scored.classNumber,
|
|
126
|
+
supportRecommendation: scored.supportRecommendation,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
return {
|
|
130
|
+
...safety,
|
|
131
|
+
visionExtraction,
|
|
132
|
+
rmrResult,
|
|
133
|
+
rawVisionText: response.text,
|
|
134
|
+
latencyMs: response.latencyMs,
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
export async function classifySoilFromDescription(description, config) {
|
|
138
|
+
const prompt = `Given this soil description: "${description}"
|
|
139
|
+
|
|
140
|
+
Classify the soil and estimate engineering properties. Respond with ONLY a JSON object:
|
|
141
|
+
{
|
|
142
|
+
"uscsSymbol": "<USCS symbol e.g. CL, SM, GP>",
|
|
143
|
+
"uscsName": "<full name e.g. Lean Clay, Silty Sand>",
|
|
144
|
+
"estimatedFrictionAngle": <degrees>,
|
|
145
|
+
"estimatedCohesion": <kPa>,
|
|
146
|
+
"estimatedUnitWeight": <kN/m3>,
|
|
147
|
+
"estimatedPermeability": "<e.g. 1e-7 m/s>",
|
|
148
|
+
"engineeringNotes": "<brief note on behavior, compressibility, strength>",
|
|
149
|
+
"confidence": <number 0-100>,
|
|
150
|
+
"warnings": ["<warning>", "<warning>"]
|
|
151
|
+
}`;
|
|
152
|
+
const response = await generateText(prompt, config, {
|
|
153
|
+
systemPrompt: 'You are an expert geotechnical engineer. Classify soils based on verbal descriptions using USCS and estimate engineering properties. Respond with JSON only.',
|
|
154
|
+
temperature: 0.1,
|
|
155
|
+
jsonMode: true,
|
|
156
|
+
maxTokens: 700,
|
|
157
|
+
});
|
|
158
|
+
const parsed = parseJsonObject(response.text);
|
|
159
|
+
const warnings = [...parsed.warnings];
|
|
160
|
+
const uscsSymbol = readString(parsed.value, 'uscsSymbol', warnings);
|
|
161
|
+
const uscsName = readString(parsed.value, 'uscsName', warnings);
|
|
162
|
+
const frictionAngle = readNumber(parsed.value, 'estimatedFrictionAngle', warnings);
|
|
163
|
+
const cohesion = readNumber(parsed.value, 'estimatedCohesion', warnings);
|
|
164
|
+
const unitWeight = readNumber(parsed.value, 'estimatedUnitWeight', warnings);
|
|
165
|
+
const permeability = readString(parsed.value, 'estimatedPermeability', warnings);
|
|
166
|
+
const engineeringNotes = readString(parsed.value, 'engineeringNotes', warnings);
|
|
167
|
+
const confidence = clampConfidence(parsed.value?.confidence, parsed.baseStatus === 'parsed' ? 70 : 0);
|
|
168
|
+
const status = deriveParseStatus(parsed.baseStatus, [uscsSymbol, uscsName, frictionAngle, cohesion, unitWeight, permeability].filter((value) => value !== null).length, 6);
|
|
169
|
+
const safety = createParseSafety(status, confidence, combineWarnings(warnings, normalizeWarnings(parsed.value?.warnings)));
|
|
170
|
+
return {
|
|
171
|
+
...safety,
|
|
172
|
+
description,
|
|
173
|
+
uscsSymbol,
|
|
174
|
+
uscsName,
|
|
175
|
+
estimatedProperties: {
|
|
176
|
+
frictionAngle,
|
|
177
|
+
cohesion,
|
|
178
|
+
unitWeight,
|
|
179
|
+
permeability,
|
|
180
|
+
},
|
|
181
|
+
engineeringNotes,
|
|
182
|
+
rawLLMText: response.text,
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
export async function interpretBoreholeLog(imageBase64, mimeType, config, boreholeId) {
|
|
186
|
+
const prompt = `Extract structured data from this borehole log image. Respond with ONLY a JSON object:
|
|
187
|
+
{
|
|
188
|
+
"boreholeId": "<ID if visible, or 'BH-unknown'>",
|
|
189
|
+
"totalDepth": <number in meters>,
|
|
190
|
+
"waterTableDepth": <number in meters or null>,
|
|
191
|
+
"layers": [
|
|
192
|
+
{
|
|
193
|
+
"depthFrom": <m>,
|
|
194
|
+
"depthTo": <m>,
|
|
195
|
+
"description": "<soil/rock description>",
|
|
196
|
+
"uscsSymbol": "<USCS if identifiable>",
|
|
197
|
+
"sptN": <number or null>,
|
|
198
|
+
"waterContent": <percent or null>,
|
|
199
|
+
"notes": "<any additional notes>"
|
|
200
|
+
}
|
|
201
|
+
],
|
|
202
|
+
"summary": "<brief engineering summary of the borehole>",
|
|
203
|
+
"confidence": <number 0-100>,
|
|
204
|
+
"warnings": ["<warning>", "<warning>"]
|
|
205
|
+
}`;
|
|
206
|
+
const response = await generateVision(prompt, imageBase64, mimeType, config, {
|
|
207
|
+
systemPrompt: 'You are an expert geotechnical engineer extracting data from borehole log documents. Be precise with depths, descriptions, and test values. Respond with JSON only.',
|
|
208
|
+
temperature: 0.1,
|
|
209
|
+
maxTokens: 2200,
|
|
210
|
+
});
|
|
211
|
+
const parsed = parseJsonObject(response.text);
|
|
212
|
+
const warnings = [...parsed.warnings];
|
|
213
|
+
const parsedLayers = Array.isArray(parsed.value?.layers)
|
|
214
|
+
? parsed.value?.layers
|
|
215
|
+
: [];
|
|
216
|
+
if (!Array.isArray(parsed.value?.layers)) {
|
|
217
|
+
warnings.push('Missing or invalid "layers" array.');
|
|
218
|
+
}
|
|
219
|
+
const layers = parsedLayers.map((layer) => {
|
|
220
|
+
const layerWarnings = [];
|
|
221
|
+
const item = {
|
|
222
|
+
depthFrom: readNumber(layer, 'depthFrom', layerWarnings),
|
|
223
|
+
depthTo: readNumber(layer, 'depthTo', layerWarnings),
|
|
224
|
+
description: readString(layer, 'description', layerWarnings),
|
|
225
|
+
uscsSymbol: readString(layer, 'uscsSymbol', []),
|
|
226
|
+
sptN: layer.sptN == null ? null : readNumber(layer, 'sptN', layerWarnings),
|
|
227
|
+
waterContent: layer.waterContent == null ? null : readNumber(layer, 'waterContent', layerWarnings),
|
|
228
|
+
notes: readString(layer, 'notes', []),
|
|
229
|
+
};
|
|
230
|
+
warnings.push(...layerWarnings.map((warning) => `Layer warning: ${warning}`));
|
|
231
|
+
return item;
|
|
232
|
+
});
|
|
233
|
+
const totalDepth = readNumber(parsed.value, 'totalDepth', warnings);
|
|
234
|
+
const waterTableDepth = parsed.value?.waterTableDepth == null
|
|
235
|
+
? null
|
|
236
|
+
: readNumber(parsed.value, 'waterTableDepth', warnings);
|
|
237
|
+
const summary = readString(parsed.value, 'summary', warnings);
|
|
238
|
+
const resolvedBoreholeId = readString(parsed.value, 'boreholeId', []) ?? boreholeId ?? 'BH-unknown';
|
|
239
|
+
const confidence = clampConfidence(parsed.value?.confidence, parsed.baseStatus === 'parsed' ? 75 : 0);
|
|
240
|
+
const status = deriveParseStatus(parsed.baseStatus, [totalDepth, summary, layers.length > 0 ? 'layers' : null].filter((value) => value !== null)
|
|
241
|
+
.length, 3);
|
|
242
|
+
const safety = createParseSafety(status, confidence, combineWarnings(warnings, normalizeWarnings(parsed.value?.warnings)));
|
|
243
|
+
return {
|
|
244
|
+
...safety,
|
|
245
|
+
boreholeId: resolvedBoreholeId,
|
|
246
|
+
totalDepth,
|
|
247
|
+
waterTableDepth,
|
|
248
|
+
layers,
|
|
249
|
+
summary,
|
|
250
|
+
rawLLMText: response.text,
|
|
251
|
+
latencyMs: response.latencyMs,
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
export async function queryGBRDocument(question, documentBase64, mimeType, config) {
|
|
255
|
+
const response = await generateVision(`Based on this Geotechnical Baseline Report, answer the following question:\n\n${question}\n\nProvide a concise, technically accurate answer with specific values and page/section references where possible.`, documentBase64, mimeType, config, {
|
|
256
|
+
systemPrompt: 'You are an expert geotechnical engineer analyzing a Geotechnical Baseline Report (GBR). Provide precise, actionable answers referencing specific data from the document.',
|
|
257
|
+
maxTokens: 2000,
|
|
258
|
+
});
|
|
259
|
+
return { answer: response.text, latencyMs: response.latencyMs };
|
|
260
|
+
}
|
|
261
|
+
export async function interpretSensorImage(imageBase64, mimeType, config) {
|
|
262
|
+
const prompt = `Analyze this geotechnical sensor data image. Respond with ONLY a JSON object:
|
|
263
|
+
{
|
|
264
|
+
"sensorType": "<inclinometer|piezometer|extensometer|load_cell|settlement_plate|tiltmeter|other>",
|
|
265
|
+
"measurements": "<key readings and values observed>",
|
|
266
|
+
"interpretation": "<what the data shows about ground/structure behavior>",
|
|
267
|
+
"evaluation": "<whether conditions are normal, warning, or critical>",
|
|
268
|
+
"recommendations": "<recommended actions if any>",
|
|
269
|
+
"confidence": <number 0-100>,
|
|
270
|
+
"warnings": ["<warning>", "<warning>"]
|
|
271
|
+
}`;
|
|
272
|
+
const response = await generateVision(prompt, imageBase64, mimeType, config, {
|
|
273
|
+
systemPrompt: 'You are an expert geotechnical instrumentation engineer. Interpret sensor data precisely.',
|
|
274
|
+
temperature: 0.1,
|
|
275
|
+
maxTokens: 1100,
|
|
276
|
+
});
|
|
277
|
+
const parsed = parseJsonObject(response.text);
|
|
278
|
+
const warnings = [...parsed.warnings];
|
|
279
|
+
const sensorType = readString(parsed.value, 'sensorType', warnings);
|
|
280
|
+
const measurements = readString(parsed.value, 'measurements', warnings);
|
|
281
|
+
const interpretation = readString(parsed.value, 'interpretation', warnings);
|
|
282
|
+
const evaluation = readString(parsed.value, 'evaluation', warnings);
|
|
283
|
+
const recommendations = readString(parsed.value, 'recommendations', warnings);
|
|
284
|
+
const confidence = clampConfidence(parsed.value?.confidence, parsed.baseStatus === 'parsed' ? 70 : 0);
|
|
285
|
+
const status = deriveParseStatus(parsed.baseStatus, [sensorType, measurements, interpretation, evaluation, recommendations].filter((value) => value !== null).length, 5);
|
|
286
|
+
const safety = createParseSafety(status, confidence, combineWarnings(warnings, normalizeWarnings(parsed.value?.warnings)));
|
|
287
|
+
return {
|
|
288
|
+
...safety,
|
|
289
|
+
sensorType,
|
|
290
|
+
measurements,
|
|
291
|
+
interpretation,
|
|
292
|
+
evaluation,
|
|
293
|
+
recommendations,
|
|
294
|
+
rawLLMText: response.text,
|
|
295
|
+
latencyMs: response.latencyMs,
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/vision/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export type ParseStatus = 'parsed' | 'partial' | 'failed';
|
|
2
|
+
export interface ParseSafety {
|
|
3
|
+
parseStatus: ParseStatus;
|
|
4
|
+
confidence: number;
|
|
5
|
+
warnings: string[];
|
|
6
|
+
canAutoProceed: boolean;
|
|
7
|
+
}
|
|
8
|
+
export interface ParsedObjectResult {
|
|
9
|
+
value: Record<string, unknown> | null;
|
|
10
|
+
baseStatus: ParseStatus;
|
|
11
|
+
warnings: string[];
|
|
12
|
+
}
|
|
13
|
+
export declare function parseJsonObject(rawText: string): ParsedObjectResult;
|
|
14
|
+
export declare function normalizeWarnings(value: unknown): string[];
|
|
15
|
+
export declare function clampConfidence(value: unknown, fallback: number): number;
|
|
16
|
+
export declare function deriveParseStatus(baseStatus: ParseStatus, presentCount: number, requiredCount: number): ParseStatus;
|
|
17
|
+
export declare function createParseSafety(status: ParseStatus, confidence: number, warnings: string[]): ParseSafety;
|
|
18
|
+
export declare function readString(source: Record<string, unknown> | null, key: string, warnings: string[]): string | null;
|
|
19
|
+
export declare function readNumber(source: Record<string, unknown> | null, key: string, warnings: string[]): number | null;
|
|
20
|
+
//# sourceMappingURL=parse.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../../src/vision/parse.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAC;AAE1D,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,WAAW,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,cAAc,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACtC,UAAU,EAAE,WAAW,CAAC;IACxB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAID,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,kBAAkB,CA4BnE;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,EAAE,CAK1D;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAIxE;AAED,wBAAgB,iBAAiB,CAC/B,UAAU,EAAE,WAAW,EACvB,YAAY,EAAE,MAAM,EACpB,aAAa,EAAE,MAAM,GACpB,WAAW,CAKb;AAED,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,WAAW,EACnB,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAAE,GACjB,WAAW,CAOb;AAED,wBAAgB,UAAU,CACxB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,EACtC,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM,EAAE,GACjB,MAAM,GAAG,IAAI,CAKf;AAED,wBAAgB,UAAU,CACxB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,EACtC,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM,EAAE,GACjB,MAAM,GAAG,IAAI,CAMf"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
const MIN_AUTO_PROCEED_CONFIDENCE = 70;
|
|
2
|
+
export function parseJsonObject(rawText) {
|
|
3
|
+
const cleaned = rawText.replace(/```json\s*/gi, '').replace(/```/g, '').trim();
|
|
4
|
+
if (!cleaned) {
|
|
5
|
+
return {
|
|
6
|
+
value: null,
|
|
7
|
+
baseStatus: 'failed',
|
|
8
|
+
warnings: ['Model returned an empty response.'],
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
try {
|
|
12
|
+
const parsed = JSON.parse(cleaned);
|
|
13
|
+
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
|
|
14
|
+
return {
|
|
15
|
+
value: null,
|
|
16
|
+
baseStatus: 'failed',
|
|
17
|
+
warnings: ['Model response was valid JSON but not an object.'],
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
return { value: parsed, baseStatus: 'parsed', warnings: [] };
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
return {
|
|
24
|
+
value: null,
|
|
25
|
+
baseStatus: 'failed',
|
|
26
|
+
warnings: ['Model response was not valid JSON.'],
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
export function normalizeWarnings(value) {
|
|
31
|
+
if (!Array.isArray(value))
|
|
32
|
+
return [];
|
|
33
|
+
return value
|
|
34
|
+
.map((item) => (typeof item === 'string' ? item.trim() : ''))
|
|
35
|
+
.filter(Boolean);
|
|
36
|
+
}
|
|
37
|
+
export function clampConfidence(value, fallback) {
|
|
38
|
+
const num = typeof value === 'number' ? value : Number(value);
|
|
39
|
+
if (!Number.isFinite(num))
|
|
40
|
+
return fallback;
|
|
41
|
+
return Math.max(0, Math.min(100, Math.round(num)));
|
|
42
|
+
}
|
|
43
|
+
export function deriveParseStatus(baseStatus, presentCount, requiredCount) {
|
|
44
|
+
if (baseStatus === 'failed')
|
|
45
|
+
return 'failed';
|
|
46
|
+
if (presentCount <= 0)
|
|
47
|
+
return 'failed';
|
|
48
|
+
if (presentCount >= requiredCount)
|
|
49
|
+
return 'parsed';
|
|
50
|
+
return 'partial';
|
|
51
|
+
}
|
|
52
|
+
export function createParseSafety(status, confidence, warnings) {
|
|
53
|
+
return {
|
|
54
|
+
parseStatus: status,
|
|
55
|
+
confidence: clampConfidence(confidence, 0),
|
|
56
|
+
warnings,
|
|
57
|
+
canAutoProceed: status === 'parsed' && confidence >= MIN_AUTO_PROCEED_CONFIDENCE,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
export function readString(source, key, warnings) {
|
|
61
|
+
const value = source?.[key];
|
|
62
|
+
if (typeof value === 'string' && value.trim())
|
|
63
|
+
return value.trim();
|
|
64
|
+
warnings.push(`Missing or invalid string field "${key}".`);
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
export function readNumber(source, key, warnings) {
|
|
68
|
+
const value = source?.[key];
|
|
69
|
+
const num = typeof value === 'number' ? value : Number(value);
|
|
70
|
+
if (Number.isFinite(num))
|
|
71
|
+
return num;
|
|
72
|
+
warnings.push(`Missing or invalid numeric field "${key}".`);
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=parse.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse.js","sourceRoot":"","sources":["../../src/vision/parse.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@geotechcli/core",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Shared computation and LLM engine for geotechCLI",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js"
|
|
12
|
+
},
|
|
13
|
+
"./llm": {
|
|
14
|
+
"types": "./dist/llm/index.d.ts",
|
|
15
|
+
"import": "./dist/llm/index.js"
|
|
16
|
+
},
|
|
17
|
+
"./geo": {
|
|
18
|
+
"types": "./dist/geo/index.d.ts",
|
|
19
|
+
"import": "./dist/geo/index.js"
|
|
20
|
+
},
|
|
21
|
+
"./config": {
|
|
22
|
+
"types": "./dist/config/index.d.ts",
|
|
23
|
+
"import": "./dist/config/index.js"
|
|
24
|
+
},
|
|
25
|
+
"./meta": {
|
|
26
|
+
"types": "./dist/meta/index.d.ts",
|
|
27
|
+
"import": "./dist/meta/index.js"
|
|
28
|
+
},
|
|
29
|
+
"./db/redis": {
|
|
30
|
+
"types": "./dist/db/redis.d.ts",
|
|
31
|
+
"import": "./dist/db/redis.js"
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
"scripts": {
|
|
35
|
+
"build": "tsc",
|
|
36
|
+
"dev": "tsc --watch",
|
|
37
|
+
"clean": "rm -rf dist",
|
|
38
|
+
"test": "vitest run",
|
|
39
|
+
"lint": "tsc --noEmit"
|
|
40
|
+
},
|
|
41
|
+
"dependencies": {
|
|
42
|
+
"zod": "^3.24.0"
|
|
43
|
+
},
|
|
44
|
+
"devDependencies": {
|
|
45
|
+
"typescript": "^5.7.0",
|
|
46
|
+
"vitest": "^3.1.0"
|
|
47
|
+
},
|
|
48
|
+
"files": [
|
|
49
|
+
"dist"
|
|
50
|
+
],
|
|
51
|
+
"publishConfig": {
|
|
52
|
+
"access": "public"
|
|
53
|
+
},
|
|
54
|
+
"license": "SEE LICENSE IN LICENSE"
|
|
55
|
+
}
|