agentboss 0.1.0 → 0.1.1
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/bin/aboss.js +288 -288
- package/client/dist/assets/{index-DBj1Ujlx.js → index-CsVml4AS.js} +49 -49
- package/client/dist/index.html +1 -1
- package/package.json +1 -1
- package/server/analysis/job.js +54 -8
- package/server/analysis/report-builder.js +574 -581
- package/server/analysis/scoring-v2.js +122 -72
- package/server/analysis/thresholds-v2.js +364 -358
- package/server/llm/analysis-prompt.js +173 -162
- package/server/llm/cli-runner.js +18 -2
- package/server/llm/judge.js +6 -1
- package/server/llm/session-analyzer.js +10 -1
package/client/dist/index.html
CHANGED
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
} catch (e) {}
|
|
26
26
|
})();
|
|
27
27
|
</script>
|
|
28
|
-
<script type="module" crossorigin src="/assets/index-
|
|
28
|
+
<script type="module" crossorigin src="/assets/index-CsVml4AS.js"></script>
|
|
29
29
|
<link rel="stylesheet" crossorigin href="/assets/index-C1wFD_Vo.css">
|
|
30
30
|
</head>
|
|
31
31
|
<body>
|
package/package.json
CHANGED
package/server/analysis/job.js
CHANGED
|
@@ -40,14 +40,51 @@ function buildDateList(days) {
|
|
|
40
40
|
for (let i = 0; i <= days; i++) {
|
|
41
41
|
const d = new Date(now);
|
|
42
42
|
d.setDate(d.getDate() - i);
|
|
43
|
-
|
|
44
|
-
const mm = String(d.getMonth() + 1).padStart(2, '0');
|
|
45
|
-
const dd = String(d.getDate()).padStart(2, '0');
|
|
46
|
-
dates.push(`${yyyy}-${mm}-${dd}`);
|
|
43
|
+
dates.push(formatDate(d));
|
|
47
44
|
}
|
|
48
45
|
return dates; // already most-recent first
|
|
49
46
|
}
|
|
50
47
|
|
|
48
|
+
/**
|
|
49
|
+
* Local-time YYYY-MM-DD for a Date. Must match buildDateList so the
|
|
50
|
+
* "today" string we compute lines up with the date strings we iterate.
|
|
51
|
+
*/
|
|
52
|
+
function formatDate(d) {
|
|
53
|
+
const yyyy = d.getFullYear();
|
|
54
|
+
const mm = String(d.getMonth() + 1).padStart(2, '0');
|
|
55
|
+
const dd = String(d.getDate()).padStart(2, '0');
|
|
56
|
+
return `${yyyy}-${mm}-${dd}`;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Pick the id of the "currently active" session for `date` — defined
|
|
61
|
+
* (per user spec) as the today-bucket session with the largest
|
|
62
|
+
* ended_at. Returns null if `date` isn't today or the bucket is empty.
|
|
63
|
+
* We skip this session in the job so we don't analyze a still-growing
|
|
64
|
+
* conversation; the next job pass will pick it up once it settles.
|
|
65
|
+
*
|
|
66
|
+
* @param {object} db
|
|
67
|
+
* @param {string} date YYYY-MM-DD
|
|
68
|
+
* @param {object[]} sessions candidate session rows for that date
|
|
69
|
+
* @returns {string|null} session_id to skip, or null
|
|
70
|
+
*/
|
|
71
|
+
function pickCurrentSessionId(db, date, sessions) {
|
|
72
|
+
const today = formatDate(new Date());
|
|
73
|
+
if (date !== today) return null;
|
|
74
|
+
// Compare against ALL today's sessions (not just unanalyzed) so a
|
|
75
|
+
// fully-analyzed but freshly-touched session still counts as "current"
|
|
76
|
+
// and shields a slightly older still-running session from being
|
|
77
|
+
// wrongly considered the active one.
|
|
78
|
+
const allToday = getSessionsByDate(db, today);
|
|
79
|
+
const pool = allToday.length > 0 ? allToday : sessions;
|
|
80
|
+
let best = null;
|
|
81
|
+
for (const s of pool) {
|
|
82
|
+
if (!s.ended_at) continue;
|
|
83
|
+
if (!best || s.ended_at > best.ended_at) best = s;
|
|
84
|
+
}
|
|
85
|
+
return best ? best.id : null;
|
|
86
|
+
}
|
|
87
|
+
|
|
51
88
|
// ---------------------------------------------------------------------------
|
|
52
89
|
// Per-session analyze + persist (shared by the job loop and the
|
|
53
90
|
// per-session reanalyze endpoint)
|
|
@@ -154,13 +191,15 @@ async function runAnalysisJob(db, options = {}) {
|
|
|
154
191
|
: buildDateList(days);
|
|
155
192
|
|
|
156
193
|
try {
|
|
157
|
-
// Pre-calculate total count for progress reporting
|
|
194
|
+
// Pre-calculate total count for progress reporting. Subtract the
|
|
195
|
+
// "current" (still-running) session if it falls in the candidate set.
|
|
158
196
|
let totalSessions = 0;
|
|
159
197
|
for (const date of dates) {
|
|
160
198
|
const sessions = forceReanalyze
|
|
161
199
|
? getSessionsByDate(db, date)
|
|
162
200
|
: getUnanalyzedSessions(db, date);
|
|
163
|
-
|
|
201
|
+
const skipId = pickCurrentSessionId(db, date, sessions);
|
|
202
|
+
totalSessions += sessions.filter((s) => s.id !== skipId).length;
|
|
164
203
|
}
|
|
165
204
|
|
|
166
205
|
updateAnalysisState(db, {
|
|
@@ -181,10 +220,17 @@ async function runAnalysisJob(db, options = {}) {
|
|
|
181
220
|
last_analyzed_at: null,
|
|
182
221
|
});
|
|
183
222
|
|
|
184
|
-
// 2a. Get unanalyzed sessions for this date
|
|
185
|
-
|
|
223
|
+
// 2a. Get unanalyzed sessions for this date, minus the currently-
|
|
224
|
+
// active session (today's session with the largest ended_at). We
|
|
225
|
+
// skip it so the job doesn't score a conversation that's still
|
|
226
|
+
// being written to — the next pass will catch it.
|
|
227
|
+
const rawSessions = forceReanalyze
|
|
186
228
|
? getSessionsByDate(db, date)
|
|
187
229
|
: getUnanalyzedSessions(db, date);
|
|
230
|
+
const skipId = pickCurrentSessionId(db, date, rawSessions);
|
|
231
|
+
const sessions = skipId
|
|
232
|
+
? rawSessions.filter((s) => s.id !== skipId)
|
|
233
|
+
: rawSessions;
|
|
188
234
|
|
|
189
235
|
if (sessions.length === 0) {
|
|
190
236
|
result.skipped++;
|