agentacta 1.1.1 → 1.1.2
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/db.js +2 -1
- package/indexer.js +11 -5
- package/package.json +1 -1
- package/public/app.js +14 -4
package/db.js
CHANGED
|
@@ -114,6 +114,7 @@ function init(dbPath) {
|
|
|
114
114
|
if (!cols.includes('output_tokens')) db.exec("ALTER TABLE sessions ADD COLUMN output_tokens INTEGER DEFAULT 0");
|
|
115
115
|
if (!cols.includes('cache_read_tokens')) db.exec("ALTER TABLE sessions ADD COLUMN cache_read_tokens INTEGER DEFAULT 0");
|
|
116
116
|
if (!cols.includes('cache_write_tokens')) db.exec("ALTER TABLE sessions ADD COLUMN cache_write_tokens INTEGER DEFAULT 0");
|
|
117
|
+
if (!cols.includes('models')) db.exec("ALTER TABLE sessions ADD COLUMN models TEXT");
|
|
117
118
|
|
|
118
119
|
db.close();
|
|
119
120
|
}
|
|
@@ -126,7 +127,7 @@ function createStmts(db) {
|
|
|
126
127
|
deleteSession: db.prepare('DELETE FROM sessions WHERE id = ?'),
|
|
127
128
|
deleteFileActivity: db.prepare('DELETE FROM file_activity WHERE session_id = ?'),
|
|
128
129
|
insertEvent: db.prepare(`INSERT OR REPLACE INTO events (id, session_id, timestamp, type, role, content, tool_name, tool_args, tool_result) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`),
|
|
129
|
-
upsertSession: db.prepare(`INSERT OR REPLACE INTO sessions (id, start_time, end_time, message_count, tool_count, model, summary, agent, session_type, total_cost, total_tokens, input_tokens, output_tokens, cache_read_tokens, cache_write_tokens, initial_prompt, first_message_id, first_message_timestamp) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`),
|
|
130
|
+
upsertSession: db.prepare(`INSERT OR REPLACE INTO sessions (id, start_time, end_time, message_count, tool_count, model, summary, agent, session_type, total_cost, total_tokens, input_tokens, output_tokens, cache_read_tokens, cache_write_tokens, initial_prompt, first_message_id, first_message_timestamp, models) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`),
|
|
130
131
|
upsertState: db.prepare(`INSERT OR REPLACE INTO index_state (file_path, last_offset, last_modified) VALUES (?, ?, ?)`),
|
|
131
132
|
insertFileActivity: db.prepare(`INSERT INTO file_activity (session_id, file_path, operation, timestamp) VALUES (?, ?, ?, ?)`),
|
|
132
133
|
deleteArchive: db.prepare('DELETE FROM archive WHERE session_id = ?'),
|
package/indexer.js
CHANGED
|
@@ -126,6 +126,7 @@ function indexFile(db, filePath, agentName, stmts, archiveMode) {
|
|
|
126
126
|
let msgCount = 0;
|
|
127
127
|
let toolCount = 0;
|
|
128
128
|
let model = null;
|
|
129
|
+
const modelsSet = new Set();
|
|
129
130
|
let summary = '';
|
|
130
131
|
let sessionType = null;
|
|
131
132
|
let agent = agentName;
|
|
@@ -182,7 +183,10 @@ function indexFile(db, filePath, agentName, stmts, archiveMode) {
|
|
|
182
183
|
try { obj = JSON.parse(line); } catch { continue; }
|
|
183
184
|
|
|
184
185
|
if (obj.type === 'session' || obj.type === 'model_change' || obj.type === 'thinking_level_change' || obj.type === 'custom' || obj.type === 'file-history-snapshot') {
|
|
185
|
-
if (obj.type === 'model_change'
|
|
186
|
+
if (obj.type === 'model_change' && obj.modelId) {
|
|
187
|
+
if (!model) model = obj.modelId; // First model for backwards compat
|
|
188
|
+
modelsSet.add(obj.modelId); // Collect all unique models
|
|
189
|
+
}
|
|
186
190
|
continue;
|
|
187
191
|
}
|
|
188
192
|
|
|
@@ -204,9 +208,10 @@ function indexFile(db, filePath, agentName, stmts, archiveMode) {
|
|
|
204
208
|
if (msg) {
|
|
205
209
|
sessionEnd = ts;
|
|
206
210
|
|
|
207
|
-
// Extract model from assistant messages
|
|
208
|
-
if (
|
|
209
|
-
model = msg.model;
|
|
211
|
+
// Extract model from assistant messages
|
|
212
|
+
if (msg.role === 'assistant' && msg.model && msg.model !== 'delivery-mirror' && !msg.model.startsWith('<')) {
|
|
213
|
+
if (!model) model = msg.model; // Keep first model for backwards compat
|
|
214
|
+
modelsSet.add(msg.model); // Collect all unique models
|
|
210
215
|
}
|
|
211
216
|
|
|
212
217
|
// Cost tracking
|
|
@@ -292,7 +297,8 @@ function indexFile(db, filePath, agentName, stmts, archiveMode) {
|
|
|
292
297
|
if (/^\[(?:Mon|Tue|Wed|Thu|Fri|Sat|Sun)\s+\d{4}-/.test(p)) sessionType = 'subagent';
|
|
293
298
|
}
|
|
294
299
|
|
|
295
|
-
|
|
300
|
+
const modelsJson = modelsSet.size > 0 ? JSON.stringify([...modelsSet]) : null;
|
|
301
|
+
stmts.upsertSession.run(sessionId, sessionStart, sessionEnd, msgCount, toolCount, model, summary, agent, sessionType, totalCost, totalTokens, totalInputTokens, totalOutputTokens, totalCacheReadTokens, totalCacheWriteTokens, initialPrompt, firstMessageId, firstMessageTimestamp, modelsJson);
|
|
296
302
|
for (const ev of pendingEvents) stmts.insertEvent.run(...ev);
|
|
297
303
|
for (const fa of fileActivities) stmts.insertFileActivity.run(...fa);
|
|
298
304
|
|
package/package.json
CHANGED
package/public/app.js
CHANGED
|
@@ -113,6 +113,16 @@ function fmtTimeOnly(ts) {
|
|
|
113
113
|
return new Date(ts).toLocaleTimeString('en-US', { hour: 'numeric', minute: '2-digit', hour12: true });
|
|
114
114
|
}
|
|
115
115
|
|
|
116
|
+
function renderModelTags(s) {
|
|
117
|
+
// Prefer models array if present, fall back to single model
|
|
118
|
+
let models = [];
|
|
119
|
+
if (s.models) {
|
|
120
|
+
try { models = JSON.parse(s.models); } catch {}
|
|
121
|
+
}
|
|
122
|
+
if (!models.length && s.model) models = [s.model];
|
|
123
|
+
return models.map(m => `<span class="session-model">${escHtml(m)}</span>`).join('');
|
|
124
|
+
}
|
|
125
|
+
|
|
116
126
|
function renderSessionItem(s) {
|
|
117
127
|
const duration = fmtDuration(s.start_time, s.end_time);
|
|
118
128
|
const timeRange = `${fmtTime(s.start_time)} → ${s.end_time ? fmtTimeOnly(s.end_time) : 'now'}`;
|
|
@@ -121,10 +131,10 @@ function renderSessionItem(s) {
|
|
|
121
131
|
<div class="session-item" data-id="${s.id}">
|
|
122
132
|
<div class="session-header">
|
|
123
133
|
<span class="session-time">${timeRange} · ${duration}</span>
|
|
124
|
-
<span style="display:flex;gap:6px;align-items:center">
|
|
134
|
+
<span style="display:flex;gap:6px;align-items:center;flex-wrap:wrap">
|
|
125
135
|
${s.agent && s.agent !== 'main' ? `<span class="session-agent">${escHtml(s.agent)}</span>` : ''}
|
|
126
136
|
${s.session_type ? `<span class="session-type">${escHtml(s.session_type)}</span>` : ''}
|
|
127
|
-
${
|
|
137
|
+
${renderModelTags(s)}
|
|
128
138
|
</span>
|
|
129
139
|
</div>
|
|
130
140
|
<div class="session-summary">${escHtml(truncate(s.summary || 'No summary', 120))}</div>
|
|
@@ -307,10 +317,10 @@ async function viewSession(id) {
|
|
|
307
317
|
<div class="session-item" style="cursor:default">
|
|
308
318
|
<div class="session-header">
|
|
309
319
|
<span class="session-time">${fmtDate(s.start_time)} · ${fmtTimeShort(s.start_time)} – ${fmtTimeShort(s.end_time)}</span>
|
|
310
|
-
<span style="display:flex;gap:6px;align-items:center">
|
|
320
|
+
<span style="display:flex;gap:6px;align-items:center;flex-wrap:wrap">
|
|
311
321
|
${s.agent && s.agent !== 'main' ? `<span class="session-agent">${escHtml(s.agent)}</span>` : ''}
|
|
312
322
|
${s.session_type ? `<span class="session-type">${escHtml(s.session_type)}</span>` : ''}
|
|
313
|
-
${
|
|
323
|
+
${renderModelTags(s)}
|
|
314
324
|
</span>
|
|
315
325
|
</div>
|
|
316
326
|
<div class="session-meta" style="display:grid;grid-template-columns:repeat(2,1fr);gap:6px 16px">
|