@goodandready/dsh-goal 0.2.1 → 0.2.3
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/README.md +12 -0
- package/README.ru.md +12 -0
- package/README.zh.md +12 -0
- package/lib/card-form-state.js +65 -21
- package/lib/client.js +4384 -2249
- package/lib/command-handler.js +51 -59
- package/lib/engine-prompt.js +57 -0
- package/lib/engine-reports.js +114 -0
- package/lib/engine-store.js +142 -0
- package/lib/goal-engine-constants.js +100 -0
- package/lib/goal-engine.js +579 -1009
- package/lib/index.js +452 -980
- package/lib/routes.js +294 -0
- package/lib/tools.js +294 -0
- package/lib/updater.js +317 -0
- package/package.json +4 -5
- package/docs/design/DESIGN.md +0 -184
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Enums and helpers for DSH Goal Engine
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export const GoalState = {
|
|
6
|
+
IDLE: 'IDLE',
|
|
7
|
+
PLANNING: 'PLANNING',
|
|
8
|
+
RUNNING: 'RUNNING',
|
|
9
|
+
PAUSED: 'PAUSED',
|
|
10
|
+
COMPLETED: 'COMPLETED',
|
|
11
|
+
FAILED: 'FAILED',
|
|
12
|
+
CANCELLED: 'CANCELLED',
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export const MilestoneStatus = {
|
|
16
|
+
PENDING: 'pending',
|
|
17
|
+
IN_PROGRESS: 'in_progress',
|
|
18
|
+
COMPLETED: 'completed',
|
|
19
|
+
FAILED: 'failed',
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Format total elapsed seconds into concise string (e.g. "2s", "45s", "1m 15s", "2h 5m")
|
|
24
|
+
* @param {number} totalSeconds
|
|
25
|
+
* @returns {string}
|
|
26
|
+
*/
|
|
27
|
+
export function formatElapsed(totalSeconds) {
|
|
28
|
+
const sec = Math.max(0, Math.floor(totalSeconds));
|
|
29
|
+
if (sec < 60) return `${sec}s`;
|
|
30
|
+
const mins = Math.floor(sec / 60);
|
|
31
|
+
const remainingSec = sec % 60;
|
|
32
|
+
if (mins < 60) {
|
|
33
|
+
return remainingSec > 0 ? `${mins}m ${remainingSec}s` : `${mins}m`;
|
|
34
|
+
}
|
|
35
|
+
const hours = Math.floor(mins / 60);
|
|
36
|
+
const remainingMins = mins % 60;
|
|
37
|
+
return remainingMins > 0 ? `${hours}h ${remainingMins}m` : `${hours}h`;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Format estimated remaining time (ETA)
|
|
42
|
+
* @param {number|null} seconds
|
|
43
|
+
* @returns {string|null}
|
|
44
|
+
*/
|
|
45
|
+
export function formatETA(seconds) {
|
|
46
|
+
if (seconds == null || isNaN(seconds)) return null;
|
|
47
|
+
const sec = Math.max(0, Math.floor(seconds));
|
|
48
|
+
if (sec < 60) return `~${sec}s`;
|
|
49
|
+
const mins = Math.round(sec / 60);
|
|
50
|
+
if (mins < 60) return `~${mins}m`;
|
|
51
|
+
const hours = Math.floor(mins / 60);
|
|
52
|
+
const remainingMins = mins % 60;
|
|
53
|
+
return remainingMins > 0 ? `~${hours}h ${remainingMins}m` : `~${hours}h`;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Detect language of text (Chinese characters -> zh, otherwise en)
|
|
58
|
+
* @param {string} text
|
|
59
|
+
* @param {string} [fallback='en']
|
|
60
|
+
* @returns {'en' | 'zh'}
|
|
61
|
+
*/
|
|
62
|
+
export function detectLanguage(text, fallback = 'en') {
|
|
63
|
+
if (!text || typeof text !== 'string') return fallback;
|
|
64
|
+
if (/[\u4e00-\u9fa5]/.test(text)) {
|
|
65
|
+
return 'zh';
|
|
66
|
+
}
|
|
67
|
+
return 'en';
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Extract session ID from invocation or HTTP request
|
|
72
|
+
* @param {any} invocationOrReq
|
|
73
|
+
* @param {string} [fallback='default']
|
|
74
|
+
* @returns {string}
|
|
75
|
+
*/
|
|
76
|
+
export function sessionIdOf(invocationOrReq, fallback = 'default') {
|
|
77
|
+
if (!invocationOrReq) return fallback;
|
|
78
|
+
try {
|
|
79
|
+
if (invocationOrReq.sessionId) return String(invocationOrReq.sessionId);
|
|
80
|
+
if (invocationOrReq.session) {
|
|
81
|
+
return String(invocationOrReq.session.id || invocationOrReq.session.header?.id || fallback);
|
|
82
|
+
}
|
|
83
|
+
if (invocationOrReq.data?.sessionId) return String(invocationOrReq.data.sessionId);
|
|
84
|
+
if (invocationOrReq.agent?.session) {
|
|
85
|
+
return String(invocationOrReq.agent.session.id || invocationOrReq.agent.session.header?.id || fallback);
|
|
86
|
+
}
|
|
87
|
+
if (invocationOrReq.headers) {
|
|
88
|
+
const headerSid = invocationOrReq.headers['x-dsh-session-id'];
|
|
89
|
+
if (headerSid) return String(headerSid);
|
|
90
|
+
if (invocationOrReq.url) {
|
|
91
|
+
const url = new URL(invocationOrReq.url, 'http://localhost');
|
|
92
|
+
const querySid = url.searchParams.get('sessionId') || url.searchParams.get('session');
|
|
93
|
+
if (querySid) return String(querySid);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
} catch (err) {
|
|
97
|
+
// Non-fatal inspection error on malformed request or object
|
|
98
|
+
}
|
|
99
|
+
return fallback;
|
|
100
|
+
}
|