@owloops/browserbird 1.4.20 → 1.4.22

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.
@@ -496,8 +496,8 @@ function getSessionTokenStats(channelId, threadId) {
496
496
  function getSessionCount() {
497
497
  return getDb().prepare("SELECT COUNT(*) as count FROM sessions").get().count;
498
498
  }
499
- function deleteStaleSessions(ttlHours) {
500
- const result = getDb().prepare(`DELETE FROM sessions WHERE last_active < datetime('now', ? || ' hours')`).run(`-${ttlHours}`);
499
+ function deleteOldSessions(retentionDays) {
500
+ const result = getDb().prepare(`DELETE FROM sessions WHERE last_active < datetime('now', ? || ' days')`).run(`-${retentionDays}`);
501
501
  return Number(result.changes);
502
502
  }
503
503
  function updateSessionProviderId(uid, providerSessionId) {
@@ -731,6 +731,9 @@ function claimNextJob() {
731
731
  };
732
732
  });
733
733
  }
734
+ function getJobStatus(jobId) {
735
+ return getDb().prepare("SELECT status FROM jobs WHERE id = ?").get(jobId)?.status;
736
+ }
734
737
  function completeJob(jobId, result) {
735
738
  getDb().prepare(`UPDATE jobs SET status = 'completed', completed_at = datetime('now'), result = ?
736
739
  WHERE id = ?`).run(result ?? null, jobId);
@@ -984,7 +987,7 @@ var db_exports = /* @__PURE__ */ __exportAll({
984
987
  deleteOldJobs: () => deleteOldJobs,
985
988
  deleteOldLogs: () => deleteOldLogs,
986
989
  deleteOldMessages: () => deleteOldMessages,
987
- deleteStaleSessions: () => deleteStaleSessions,
990
+ deleteOldSessions: () => deleteOldSessions,
988
991
  ensureSystemCronJob: () => ensureSystemCronJob,
989
992
  failJob: () => failJob,
990
993
  failStaleJobs: () => failStaleJobs,
@@ -994,6 +997,7 @@ var db_exports = /* @__PURE__ */ __exportAll({
994
997
  getEnabledCronJobs: () => getEnabledCronJobs,
995
998
  getFlightStats: () => getFlightStats,
996
999
  getJobStats: () => getJobStats,
1000
+ getJobStatus: () => getJobStatus,
997
1001
  getLastInboundMessage: () => getLastInboundMessage,
998
1002
  getMessageStats: () => getMessageStats,
999
1003
  getRecentLogs: () => getRecentLogs,
@@ -1031,4 +1035,4 @@ var db_exports = /* @__PURE__ */ __exportAll({
1031
1035
  });
1032
1036
 
1033
1037
  //#endregion
1034
- export { updateSessionProviderId as $, completeCronRun as A, listFlights as B, failStaleJobs as C, retryAllFailedJobs as D, listJobs as E, ensureSystemCronJob as F, deleteStaleSessions as G, updateCronJob as H, getCronJob as I, getSessionCount as J, findSession as K, getEnabledCronJobs as L, createCronRun as M, deleteCronJob as N, retryJob as O, deleteOldCronRuns as P, touchSession as Q, getFlightStats as R, failJob as S, hasPendingCronJob as T, updateCronJobStatus as U, setCronJobEnabled as V, createSession as W, getSessionTokenStats as X, getSessionMessages as Y, listSessions as Z, clearJobs as _, getSetting as a, resolveByUid as at, deleteJob as b, getUserCount as c, getRecentLogs as d, shortUid as et, insertLog as f, claimNextJob as g, logMessage as h, createUser as i, optimizeDatabase as it, createCronJob as j, SYSTEM_CRON_PREFIX as k, setSetting as l, getMessageStats as m, resolveDbPath as n, getDb as nt, getUserByEmail as o, logger as ot, deleteOldMessages as p, getSession as q, resolveDbPathFromArgv as r, openDatabase as rt, getUserById as s, db_exports as t, closeDatabase as tt, deleteOldLogs as u, completeJob as v, getJobStats as w, deleteOldJobs as x, createJob as y, listCronJobs as z };
1038
+ export { touchSession as $, SYSTEM_CRON_PREFIX as A, listCronJobs as B, failStaleJobs as C, listJobs as D, hasPendingCronJob as E, deleteOldCronRuns as F, createSession as G, setCronJobEnabled as H, ensureSystemCronJob as I, getSession as J, deleteOldSessions as K, getCronJob as L, createCronJob as M, createCronRun as N, retryAllFailedJobs as O, deleteCronJob as P, listSessions as Q, getEnabledCronJobs as R, failJob as S, getJobStatus as T, updateCronJob as U, listFlights as V, updateCronJobStatus as W, getSessionMessages as X, getSessionCount as Y, getSessionTokenStats as Z, clearJobs as _, getSetting as a, optimizeDatabase as at, deleteJob as b, getUserCount as c, getRecentLogs as d, updateSessionProviderId as et, insertLog as f, claimNextJob as g, logMessage as h, createUser as i, openDatabase as it, completeCronRun as j, retryJob as k, setSetting as l, getMessageStats as m, resolveDbPath as n, closeDatabase as nt, getUserByEmail as o, resolveByUid as ot, deleteOldMessages as p, findSession as q, resolveDbPathFromArgv as r, getDb as rt, getUserById as s, logger as st, db_exports as t, shortUid as tt, deleteOldLogs as u, completeJob as v, getJobStats as w, deleteOldJobs as x, createJob as y, getFlightStats as z };
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { $ as updateSessionProviderId, A as completeCronRun, B as listFlights, C as failStaleJobs, D as retryAllFailedJobs, E as listJobs, F as ensureSystemCronJob, G as deleteStaleSessions, H as updateCronJob, I as getCronJob, J as getSessionCount, K as findSession, L as getEnabledCronJobs, M as createCronRun, N as deleteCronJob, O as retryJob, P as deleteOldCronRuns, Q as touchSession, R as getFlightStats, S as failJob, T as hasPendingCronJob, U as updateCronJobStatus, V as setCronJobEnabled, W as createSession, X as getSessionTokenStats, Y as getSessionMessages, Z as listSessions, _ as clearJobs, a as getSetting, at as resolveByUid, b as deleteJob, c as getUserCount, d as getRecentLogs, et as shortUid, f as insertLog, g as claimNextJob, h as logMessage, i as createUser, it as optimizeDatabase, j as createCronJob, k as SYSTEM_CRON_PREFIX, l as setSetting, m as getMessageStats, n as resolveDbPath, nt as getDb, o as getUserByEmail, ot as logger, p as deleteOldMessages, q as getSession, r as resolveDbPathFromArgv, rt as openDatabase, s as getUserById, tt as closeDatabase, u as deleteOldLogs, v as completeJob, w as getJobStats, x as deleteOldJobs, y as createJob, z as listCronJobs } from "./db-CyQcrilg.mjs";
1
+ import { $ as touchSession, A as SYSTEM_CRON_PREFIX, B as listCronJobs, C as failStaleJobs, D as listJobs, E as hasPendingCronJob, F as deleteOldCronRuns, G as createSession, H as setCronJobEnabled, I as ensureSystemCronJob, J as getSession, K as deleteOldSessions, L as getCronJob, M as createCronJob, N as createCronRun, O as retryAllFailedJobs, P as deleteCronJob, Q as listSessions, R as getEnabledCronJobs, S as failJob, T as getJobStatus, U as updateCronJob, V as listFlights, W as updateCronJobStatus, X as getSessionMessages, Y as getSessionCount, Z as getSessionTokenStats, _ as clearJobs, a as getSetting, at as optimizeDatabase, b as deleteJob, c as getUserCount, d as getRecentLogs, et as updateSessionProviderId, f as insertLog, g as claimNextJob, h as logMessage, i as createUser, it as openDatabase, j as completeCronRun, k as retryJob, l as setSetting, m as getMessageStats, n as resolveDbPath, nt as closeDatabase, o as getUserByEmail, ot as resolveByUid, p as deleteOldMessages, q as findSession, r as resolveDbPathFromArgv, rt as getDb, s as getUserById, st as logger, tt as shortUid, u as deleteOldLogs, v as completeJob, w as getJobStats, x as deleteOldJobs, y as createJob, z as getFlightStats } from "./db-BNF1vZIm.mjs";
2
2
  import { createRequire } from "node:module";
3
3
  import { parseArgs, styleText } from "node:util";
4
4
  import { existsSync, readFileSync, renameSync, writeFileSync } from "node:fs";
@@ -122,8 +122,8 @@ function unknownSubcommand(subcommand, command, validCommands) {
122
122
  /** @fileoverview ASCII banner displayed on daemon startup and in help text. */
123
123
  const pkg = createRequire(import.meta.url)("../package.json");
124
124
  const buildInfo = [];
125
- buildInfo.push(`commit: ${"e530e3fd3fc189a83f22c2e98b41356fd1c894cc".substring(0, 7)}`);
126
- buildInfo.push(`built: 2026-03-16T00:28:40+04:00`);
125
+ buildInfo.push(`commit: ${"6b68cb0894c3003327ae0831a48a83038a9a2f48".substring(0, 7)}`);
126
+ buildInfo.push(`built: 2026-03-17T20:43:27+04:00`);
127
127
  const buildString = buildInfo.length > 0 ? ` (${buildInfo.join(", ")})` : "";
128
128
  const VERSION = `browserbird ${pkg.version}${buildString}`;
129
129
  const BIRD = [
@@ -2009,10 +2009,12 @@ async function processJob(job) {
2009
2009
  } finally {
2010
2010
  if (cronRun != null) completeCronRun(cronRun.uid, finalStatus === "completed" ? "success" : "error", resultText, errorText);
2011
2011
  if (isCronRun && job.cron_job_uid != null) {
2012
- const cronJob = getCronJob(job.cron_job_uid);
2013
- if (cronJob != null) {
2014
- const newFailureCount = finalStatus === "failed" ? cronJob.failure_count + 1 : cronJob.failure_count;
2015
- updateCronJobStatus(job.cron_job_uid, finalStatus, newFailureCount);
2012
+ if (!(getJobStatus(job.id) === "failed" && finalStatus === "failed")) {
2013
+ const cronJob = getCronJob(job.cron_job_uid);
2014
+ if (cronJob != null) {
2015
+ const newFailureCount = finalStatus === "failed" ? cronJob.failure_count + 1 : 0;
2016
+ updateCronJobStatus(job.cron_job_uid, finalStatus, newFailureCount);
2017
+ }
2016
2018
  }
2017
2019
  }
2018
2020
  const invalidatePayload = { resource: isCronRun ? "birds" : "sessions" };
@@ -2099,9 +2101,9 @@ function resolveSession(channelId, threadTs, config, nameToId) {
2099
2101
  isNew: true
2100
2102
  };
2101
2103
  }
2102
- function expireStaleSessions(ttlHours) {
2103
- const deleted = deleteStaleSessions(ttlHours);
2104
- if (deleted > 0) logger.info(`expired ${deleted} stale session(s)`);
2104
+ function deleteExpiredSessions(retentionDays) {
2105
+ const deleted = deleteOldSessions(retentionDays);
2106
+ if (deleted > 0) logger.info(`deleted ${deleted} expired session(s)`);
2105
2107
  return deleted;
2106
2108
  }
2107
2109
 
@@ -2711,13 +2713,13 @@ function registerSystemCronJobs(config, retentionDays) {
2711
2713
  const cleanupName = `${SYSTEM_CRON_PREFIX}db_cleanup__`;
2712
2714
  const optimizeName = `${SYSTEM_CRON_PREFIX}db_optimize__`;
2713
2715
  systemHandlers.set(cleanupName, () => {
2714
- expireStaleSessions(config.sessions.ttlHours);
2716
+ const sessions = deleteExpiredSessions(retentionDays);
2715
2717
  const msgs = deleteOldMessages(retentionDays);
2716
2718
  const runs = deleteOldCronRuns(retentionDays);
2717
2719
  const jobs = deleteOldJobs(retentionDays);
2718
2720
  const logs = deleteOldLogs(retentionDays);
2719
- if (msgs > 0 || runs > 0 || jobs > 0 || logs > 0) {
2720
- const summary = `${msgs} messages, ${runs} flight logs, ${jobs} jobs, ${logs} logs older than ${retentionDays}d`;
2721
+ if (sessions > 0 || msgs > 0 || runs > 0 || jobs > 0 || logs > 0) {
2722
+ const summary = `${sessions} sessions, ${msgs} messages, ${runs} flight logs, ${jobs} jobs, ${logs} logs older than ${retentionDays}d`;
2721
2723
  logger.info(`system cleanup: ${summary}`);
2722
2724
  return summary;
2723
2725
  }
@@ -3078,7 +3080,7 @@ function createHandler(client, getConfig, signal, getTeamId, getChannelNameToId)
3078
3080
  const { session, agent, isNew } = resolved;
3079
3081
  sessionUid = session.uid;
3080
3082
  for (const msg of messages) logMessage(channelId, threadTs, msg.userId, "in", msg.text);
3081
- touchSession(session.uid, messages.length + 1);
3083
+ touchSession(session.uid, messages.length);
3082
3084
  broadcastSSE("invalidate", { resource: "sessions" });
3083
3085
  const prompt = formatPrompt(messages);
3084
3086
  const userId = messages[messages.length - 1].userId;
@@ -3661,7 +3663,7 @@ async function handleBirdCreateSubmission(view, webClient) {
3661
3663
  logger.warn("bird_create submission missing required fields");
3662
3664
  return;
3663
3665
  }
3664
- const { createCronJob, setCronJobEnabled } = await import("./db-CyQcrilg.mjs").then((n) => n.t);
3666
+ const { createCronJob, setCronJobEnabled } = await import("./db-BNF1vZIm.mjs").then((n) => n.t);
3665
3667
  const bird = createCronJob(name, schedule, prompt, channelId || void 0, "default");
3666
3668
  if (enabledValue !== "enabled") setCronJobEnabled(bird.uid, false);
3667
3669
  await webClient.chat.postMessage({
@@ -3675,7 +3677,7 @@ async function handleBirdCreateSubmission(view, webClient) {
3675
3677
  }
3676
3678
  async function handleSessionRetry(sessionUid, userId, handler) {
3677
3679
  try {
3678
- const { getSession, getLastInboundMessage } = await import("./db-CyQcrilg.mjs").then((n) => n.t);
3680
+ const { getSession, getLastInboundMessage } = await import("./db-BNF1vZIm.mjs").then((n) => n.t);
3679
3681
  const session = getSession(sessionUid);
3680
3682
  if (!session) {
3681
3683
  logger.warn(`retry: session ${sessionUid} not found`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@owloops/browserbird",
3
- "version": "1.4.20",
3
+ "version": "1.4.22",
4
4
  "description": "AI agent orchestrator with a real browser, a cron scheduler, and a web dashboard",
5
5
  "type": "module",
6
6
  "bin": {