@yhong91/vibetime 0.1.42 → 0.1.44
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/vibetime.mjs +92 -21
- package/package.json +1 -1
package/bin/vibetime.mjs
CHANGED
|
@@ -1845,7 +1845,7 @@ function operationForTool(tool) {
|
|
|
1845
1845
|
if (["write"].includes(normalized)) {
|
|
1846
1846
|
return "write";
|
|
1847
1847
|
}
|
|
1848
|
-
if (["edit", "multiedit", "notebookedit", "apply_patch", "applypatch"].includes(normalized)) {
|
|
1848
|
+
if (["edit", "multiedit", "notebookedit", "apply_patch", "applypatch", "searchreplace"].includes(normalized)) {
|
|
1849
1849
|
return "edit";
|
|
1850
1850
|
}
|
|
1851
1851
|
return "read";
|
|
@@ -1928,7 +1928,7 @@ function countTextLines(text) {
|
|
|
1928
1928
|
}
|
|
1929
1929
|
|
|
1930
1930
|
// src/lib/constants.ts
|
|
1931
|
-
var PACKAGE_VERSION = true ? "0.1.
|
|
1931
|
+
var PACKAGE_VERSION = true ? "0.1.44" : "0.1.1";
|
|
1932
1932
|
var DEFAULT_API_URL = "http://121.196.224.82:3001";
|
|
1933
1933
|
var DEFAULT_BACKFILL_BATCH_SIZE = 50;
|
|
1934
1934
|
var DEFAULT_BACKFILL_BATCH_BYTES = 800 * 1024;
|
|
@@ -5815,6 +5815,18 @@ async function parseCopilotSessionFile(filePath, options) {
|
|
|
5815
5815
|
}
|
|
5816
5816
|
const msgTurnId = stringField(data, "turnId");
|
|
5817
5817
|
const turnId = msgTurnId !== void 0 ? `turn_${createStableHash([sessionId, msgTurnId]).slice(0, 24)}` : currentTurnId;
|
|
5818
|
+
events.push(baseCopilotEvent({
|
|
5819
|
+
ts,
|
|
5820
|
+
type: "agent.operation",
|
|
5821
|
+
operation: "model call",
|
|
5822
|
+
sessionId,
|
|
5823
|
+
turnId,
|
|
5824
|
+
cwd,
|
|
5825
|
+
project,
|
|
5826
|
+
model,
|
|
5827
|
+
confidence: "exact",
|
|
5828
|
+
metrics: { modelCalls: 1 }
|
|
5829
|
+
}));
|
|
5818
5830
|
const outputTokens = numberField(data, "outputTokens");
|
|
5819
5831
|
if (outputTokens && outputTokens > 0) {
|
|
5820
5832
|
const key = turnId || "unknown";
|
|
@@ -8138,7 +8150,11 @@ async function parseQoderCnSessionFile(filePath, options) {
|
|
|
8138
8150
|
const mapped = {
|
|
8139
8151
|
...event,
|
|
8140
8152
|
sessionId: parentSessionId,
|
|
8141
|
-
refs: {
|
|
8153
|
+
refs: {
|
|
8154
|
+
...event.refs,
|
|
8155
|
+
sourcePathHash: parentSourcePathHash,
|
|
8156
|
+
...event.sessionId && event.sessionId !== parentSessionId ? { supersededSessionId: event.sessionId } : {}
|
|
8157
|
+
}
|
|
8142
8158
|
};
|
|
8143
8159
|
return rebuildEventIdentity2(mapped);
|
|
8144
8160
|
});
|
|
@@ -8151,7 +8167,11 @@ async function parseQoderCnSessionFile(filePath, options) {
|
|
|
8151
8167
|
return validEvents.map((event) => rebuildEventIdentity2({
|
|
8152
8168
|
...event,
|
|
8153
8169
|
sessionId: dbModelCalls.rootSessionId,
|
|
8154
|
-
refs: {
|
|
8170
|
+
refs: {
|
|
8171
|
+
...event.refs,
|
|
8172
|
+
sourcePathHash: parentSourcePathHash,
|
|
8173
|
+
...event.sessionId && event.sessionId !== dbModelCalls.rootSessionId ? { supersededSessionId: event.sessionId } : {}
|
|
8174
|
+
}
|
|
8155
8175
|
}));
|
|
8156
8176
|
}
|
|
8157
8177
|
return validEvents;
|
|
@@ -8198,7 +8218,7 @@ function fileActivitiesFromQoderCnToolUse(tool, input, ts, cwd) {
|
|
|
8198
8218
|
const metrics = fileMetricsFromQoderCnToolInput(tool, input);
|
|
8199
8219
|
addResolvedPathActivity(changes, filePath, operation, ts, cwd, workdir, metrics);
|
|
8200
8220
|
}
|
|
8201
|
-
for (const edit of arrayField4(input, "edits")) {
|
|
8221
|
+
for (const edit of [...arrayField4(input, "edits"), ...arrayField4(input, "replacements")]) {
|
|
8202
8222
|
if (!isPlainObject(edit)) {
|
|
8203
8223
|
continue;
|
|
8204
8224
|
}
|
|
@@ -8207,8 +8227,8 @@ function fileActivitiesFromQoderCnToolUse(tool, input, ts, cwd) {
|
|
|
8207
8227
|
continue;
|
|
8208
8228
|
}
|
|
8209
8229
|
addResolvedPathActivity(changes, filePath, "edit", ts, cwd, workdir, {
|
|
8210
|
-
linesAdded: countTextLines(stringField(edit, "new_string")),
|
|
8211
|
-
linesRemoved: countTextLines(stringField(edit, "old_string"))
|
|
8230
|
+
linesAdded: countTextLines(stringField(edit, "new_string") || stringField(edit, "new_text")),
|
|
8231
|
+
linesRemoved: countTextLines(stringField(edit, "old_string") || stringField(edit, "original_text"))
|
|
8212
8232
|
});
|
|
8213
8233
|
}
|
|
8214
8234
|
const command = stringField(input, "command");
|
|
@@ -8225,13 +8245,13 @@ function fileMetricsFromQoderCnToolInput(tool, input) {
|
|
|
8225
8245
|
return { linesRead: numberField(input, "limit") };
|
|
8226
8246
|
}
|
|
8227
8247
|
if (normalized === "write") {
|
|
8228
|
-
const content = stringField(input, "content");
|
|
8248
|
+
const content = stringField(input, "content") || stringField(input, "file_content");
|
|
8229
8249
|
return {
|
|
8230
8250
|
linesAdded: countTextLines(content),
|
|
8231
8251
|
charsWritten: content?.length
|
|
8232
8252
|
};
|
|
8233
8253
|
}
|
|
8234
|
-
if (normalized === "edit" || normalized === "multiedit") {
|
|
8254
|
+
if (normalized === "edit" || normalized === "multiedit" || normalized === "searchreplace") {
|
|
8235
8255
|
const oldString = stringField(input, "old_string");
|
|
8236
8256
|
const newString = stringField(input, "new_string");
|
|
8237
8257
|
return {
|
|
@@ -8964,7 +8984,11 @@ async function parseQoderSessionFile(filePath, options) {
|
|
|
8964
8984
|
const mapped = {
|
|
8965
8985
|
...event,
|
|
8966
8986
|
sessionId: parentSessionId,
|
|
8967
|
-
refs: {
|
|
8987
|
+
refs: {
|
|
8988
|
+
...event.refs,
|
|
8989
|
+
sourcePathHash: parentSourcePathHash,
|
|
8990
|
+
...event.sessionId && event.sessionId !== parentSessionId ? { supersededSessionId: event.sessionId } : {}
|
|
8991
|
+
}
|
|
8968
8992
|
};
|
|
8969
8993
|
return rebuildEventIdentity3(mapped);
|
|
8970
8994
|
});
|
|
@@ -8977,7 +9001,11 @@ async function parseQoderSessionFile(filePath, options) {
|
|
|
8977
9001
|
return validEvents.map((event) => rebuildEventIdentity3({
|
|
8978
9002
|
...event,
|
|
8979
9003
|
sessionId: dbModelCalls.rootSessionId,
|
|
8980
|
-
refs: {
|
|
9004
|
+
refs: {
|
|
9005
|
+
...event.refs,
|
|
9006
|
+
sourcePathHash: parentSourcePathHash,
|
|
9007
|
+
...event.sessionId && event.sessionId !== dbModelCalls.rootSessionId ? { supersededSessionId: event.sessionId } : {}
|
|
9008
|
+
}
|
|
8981
9009
|
}));
|
|
8982
9010
|
}
|
|
8983
9011
|
return validEvents;
|
|
@@ -9024,7 +9052,7 @@ function fileActivitiesFromQoderToolUse(tool, input, ts, cwd) {
|
|
|
9024
9052
|
const metrics = fileMetricsFromQoderToolInput(tool, input);
|
|
9025
9053
|
addResolvedPathActivity(changes, filePath, operation, ts, cwd, workdir, metrics);
|
|
9026
9054
|
}
|
|
9027
|
-
for (const edit of arrayField5(input, "edits")) {
|
|
9055
|
+
for (const edit of [...arrayField5(input, "edits"), ...arrayField5(input, "replacements")]) {
|
|
9028
9056
|
if (!isPlainObject(edit)) {
|
|
9029
9057
|
continue;
|
|
9030
9058
|
}
|
|
@@ -9033,8 +9061,8 @@ function fileActivitiesFromQoderToolUse(tool, input, ts, cwd) {
|
|
|
9033
9061
|
continue;
|
|
9034
9062
|
}
|
|
9035
9063
|
addResolvedPathActivity(changes, filePath, "edit", ts, cwd, workdir, {
|
|
9036
|
-
linesAdded: countTextLines(stringField(edit, "new_string")),
|
|
9037
|
-
linesRemoved: countTextLines(stringField(edit, "old_string"))
|
|
9064
|
+
linesAdded: countTextLines(stringField(edit, "new_string") || stringField(edit, "new_text")),
|
|
9065
|
+
linesRemoved: countTextLines(stringField(edit, "old_string") || stringField(edit, "original_text"))
|
|
9038
9066
|
});
|
|
9039
9067
|
}
|
|
9040
9068
|
const command = stringField(input, "command");
|
|
@@ -9051,13 +9079,13 @@ function fileMetricsFromQoderToolInput(tool, input) {
|
|
|
9051
9079
|
return { linesRead: numberField(input, "limit") };
|
|
9052
9080
|
}
|
|
9053
9081
|
if (normalized === "write") {
|
|
9054
|
-
const content = stringField(input, "content");
|
|
9082
|
+
const content = stringField(input, "content") || stringField(input, "file_content");
|
|
9055
9083
|
return {
|
|
9056
9084
|
linesAdded: countTextLines(content),
|
|
9057
9085
|
charsWritten: content?.length
|
|
9058
9086
|
};
|
|
9059
9087
|
}
|
|
9060
|
-
if (normalized === "edit" || normalized === "multiedit") {
|
|
9088
|
+
if (normalized === "edit" || normalized === "multiedit" || normalized === "searchreplace") {
|
|
9061
9089
|
const oldString = stringField(input, "old_string");
|
|
9062
9090
|
const newString = stringField(input, "new_string");
|
|
9063
9091
|
return {
|
|
@@ -10746,11 +10774,14 @@ function buildSessionRollup(rollupKey, events) {
|
|
|
10746
10774
|
const agent = first.agent || ordered.find((event) => event.agent)?.agent;
|
|
10747
10775
|
const startedAt = ordered[0]?.ts || (/* @__PURE__ */ new Date()).toISOString();
|
|
10748
10776
|
const lastEventAt = ordered.at(-1)?.ts || startedAt;
|
|
10777
|
+
const supersededSessionIds = [...new Set(ordered.map((event) => event.refs?.supersededSessionId).filter((id) => Boolean(id) && id !== sessionId))];
|
|
10749
10778
|
const timeBuckets = /* @__PURE__ */ new Map();
|
|
10750
10779
|
const modelRollups = /* @__PURE__ */ new Map();
|
|
10751
10780
|
const toolRollups = /* @__PURE__ */ new Map();
|
|
10752
10781
|
const fileRollups = /* @__PURE__ */ new Map();
|
|
10753
10782
|
const turnRollups = /* @__PURE__ */ new Map();
|
|
10783
|
+
const turnTimings = /* @__PURE__ */ new Map();
|
|
10784
|
+
let activeTurnId;
|
|
10754
10785
|
let promptCount = 0;
|
|
10755
10786
|
let turnCount = 0;
|
|
10756
10787
|
let toolCallCount = 0;
|
|
@@ -10766,6 +10797,22 @@ function buildSessionRollup(rollupKey, events) {
|
|
|
10766
10797
|
let linesAdded = 0;
|
|
10767
10798
|
let linesRemoved = 0;
|
|
10768
10799
|
for (const event of ordered) {
|
|
10800
|
+
if (event.type === "turn.started" && event.turnId) {
|
|
10801
|
+
activeTurnId = event.turnId;
|
|
10802
|
+
const timing = turnTimings.get(event.turnId) || {};
|
|
10803
|
+
timing.taskStartedAt ??= event.ts;
|
|
10804
|
+
turnTimings.set(event.turnId, timing);
|
|
10805
|
+
}
|
|
10806
|
+
if (event.type === "model.usage" || (event.metrics?.modelCalls || 0) > 0) {
|
|
10807
|
+
const turnId = event.turnId || activeTurnId;
|
|
10808
|
+
if (turnId) {
|
|
10809
|
+
const timing = turnTimings.get(turnId) || {};
|
|
10810
|
+
if (!timing.lastCallAt || event.ts > timing.lastCallAt) {
|
|
10811
|
+
timing.lastCallAt = event.ts;
|
|
10812
|
+
}
|
|
10813
|
+
turnTimings.set(turnId, timing);
|
|
10814
|
+
}
|
|
10815
|
+
}
|
|
10769
10816
|
const eventInputTokens = Math.max(0, event.metrics?.tokensInput || 0);
|
|
10770
10817
|
const eventCachedInputTokens = Math.max(0, event.metrics?.tokensCachedInput || 0);
|
|
10771
10818
|
const eventCacheCreationInputTokens = Math.max(0, event.metrics?.tokensCacheCreationInput || 0);
|
|
@@ -10969,6 +11016,9 @@ function buildSessionRollup(rollupKey, events) {
|
|
|
10969
11016
|
fileRollups.set(pathHash, fileRollup);
|
|
10970
11017
|
}
|
|
10971
11018
|
timeBuckets.set(bucketTs, bucket);
|
|
11019
|
+
if (event.type === "turn.completed" && event.turnId === activeTurnId) {
|
|
11020
|
+
activeTurnId = void 0;
|
|
11021
|
+
}
|
|
10972
11022
|
}
|
|
10973
11023
|
const baseRollup = {
|
|
10974
11024
|
rollupKey,
|
|
@@ -10999,10 +11049,16 @@ function buildSessionRollup(rollupKey, events) {
|
|
|
10999
11049
|
modelRollups: [...modelRollups.values()].sort((a, b) => b.callCount - a.callCount || a.model.localeCompare(b.model)),
|
|
11000
11050
|
toolRollups: [...toolRollups.values()].sort((a, b) => b.callCount - a.callCount || a.tool.localeCompare(b.tool)),
|
|
11001
11051
|
fileRollups: [...fileRollups.values()].sort((a, b) => b.writes - a.writes || b.reads - a.reads || a.displayPath.localeCompare(b.displayPath)),
|
|
11002
|
-
turnRollups: [...turnRollups.values()].map((rollup) =>
|
|
11003
|
-
|
|
11004
|
-
|
|
11005
|
-
|
|
11052
|
+
turnRollups: [...turnRollups.values()].map((rollup) => {
|
|
11053
|
+
const timing = turnTimings.get(rollup.turnId);
|
|
11054
|
+
const startedAt2 = timing?.taskStartedAt || rollup.startedAt;
|
|
11055
|
+
return {
|
|
11056
|
+
...rollup,
|
|
11057
|
+
startedAt: startedAt2,
|
|
11058
|
+
durationMs: timing?.lastCallAt ? Math.max(0, Date.parse(timing.lastCallAt) - Date.parse(startedAt2)) : 0
|
|
11059
|
+
};
|
|
11060
|
+
}).sort((a, b) => a.startedAt.localeCompare(b.startedAt)),
|
|
11061
|
+
...supersededSessionIds.length > 0 ? { supersededSessionIds } : {}
|
|
11006
11062
|
};
|
|
11007
11063
|
return {
|
|
11008
11064
|
...baseRollup,
|
|
@@ -11416,7 +11472,7 @@ async function postRollupBatch(remote, rollups, options = {}) {
|
|
|
11416
11472
|
};
|
|
11417
11473
|
}
|
|
11418
11474
|
async function deleteRollupsBySource(remote, source, machine, options = {}) {
|
|
11419
|
-
const query = `source=${encodeURIComponent(source)}${options.preserveTokens ? "&preserveTokens=1" : ""}${options.allowHistoricalRewrite ? "&allowHistoricalRewrite=1" : ""}`;
|
|
11475
|
+
const query = `source=${encodeURIComponent(source)}${options.rollupKey ? `&rollupKey=${encodeURIComponent(options.rollupKey)}` : ""}${options.preserveTokens ? "&preserveTokens=1" : ""}${options.allowHistoricalRewrite ? "&allowHistoricalRewrite=1" : ""}`;
|
|
11420
11476
|
const response = await remote.fetchImpl(
|
|
11421
11477
|
joinUrl(remote.baseUrl, `/v3/agent/sessions?${query}`),
|
|
11422
11478
|
{ method: "DELETE", headers: buildHeaders(remote.token, machine) }
|
|
@@ -12273,6 +12329,21 @@ async function sendSessionRollupBatch(rollups, options, ctx) {
|
|
|
12273
12329
|
machine,
|
|
12274
12330
|
allowHistoricalRewrite: options["purge-all"] === true
|
|
12275
12331
|
});
|
|
12332
|
+
if (options.force && result.conflicts === 0) {
|
|
12333
|
+
for (const rollup of rollups) {
|
|
12334
|
+
for (const sessionId of rollup.supersededSessionIds ?? []) {
|
|
12335
|
+
try {
|
|
12336
|
+
await deleteRollupsBySource(remote, rollup.source, machine, {
|
|
12337
|
+
rollupKey: createImportKey(["rollup", rollup.source, sessionId]),
|
|
12338
|
+
allowHistoricalRewrite: options["purge-all"] === true
|
|
12339
|
+
});
|
|
12340
|
+
} catch (error) {
|
|
12341
|
+
debug(ctx, `Failed to delete superseded ${rollup.source} session ${sessionId}: ${error.message}
|
|
12342
|
+
`);
|
|
12343
|
+
}
|
|
12344
|
+
}
|
|
12345
|
+
}
|
|
12346
|
+
}
|
|
12276
12347
|
return result;
|
|
12277
12348
|
}
|
|
12278
12349
|
async function deleteSessionRollupsBySourceAPI(source, options, ctx, preserveTokens) {
|
package/package.json
CHANGED