quoroom 0.1.39 → 0.1.40

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 CHANGED
@@ -122,7 +122,7 @@ Quoroom is an open research project exploring autonomous agent collectives. Each
122
122
 
123
123
  **Credentials** — Secure credential storage for API keys and secrets. Agents list and retrieve credentials at runtime without exposing raw values in prompts or logs.
124
124
 
125
- **Auto-updates** — The server polls GitHub for new releases every 4 hours. When a new version is available, the dashboard shows a notification popup and a download row in Settings. One click downloads the installer for your platform directly no browser redirect.
125
+ **Auto-updates** — Update behavior depends on deployment mode. In local mode, the dashboard shows update controls (popup + Settings row) and lets you download/apply updates manually. In cloud mode, updates are managed automatically by the runtime with no manual update buttons in the UI.
126
126
 
127
127
  ---
128
128
 
@@ -9914,7 +9914,7 @@ var require_package = __commonJS({
9914
9914
  "package.json"(exports2, module2) {
9915
9915
  module2.exports = {
9916
9916
  name: "quoroom",
9917
- version: "0.1.39",
9917
+ version: "0.1.40",
9918
9918
  description: "Open-source local AI agent framework \u2014 Queen, Workers, Quorum. Experimental research tool.",
9919
9919
  main: "./out/mcp/server.js",
9920
9920
  bin: {
@@ -10931,6 +10931,7 @@ var require_node_cron = __commonJS({
10931
10931
  // src/server/index.ts
10932
10932
  var index_exports = {};
10933
10933
  __export(index_exports, {
10934
+ _createCloudReadyUpdateHandler: () => createCloudReadyUpdateHandler,
10934
10935
  _isLoopbackAddress: () => isLoopbackAddress,
10935
10936
  _resolveStaticDirForStart: () => resolveStaticDirForStart,
10936
10937
  _shellQuote: () => shellQuote,
@@ -11313,24 +11314,24 @@ var CHAIN_CONFIGS = {
11313
11314
  var SUPPORTED_CHAINS = ["base", "ethereum", "arbitrum", "optimism", "polygon"];
11314
11315
  var SUPPORTED_TOKENS = ["usdc", "usdt"];
11315
11316
  var QUEEN_DEFAULTS_BY_PLAN = {
11316
- none: { queenCycleGapMs: 10 * 60 * 1e3, queenMaxTurns: 30 },
11317
- // 10 min gap, 30 turns
11318
- pro: { queenCycleGapMs: 5 * 60 * 1e3, queenMaxTurns: 30 },
11319
- // 5 min gap, 30 turns
11320
- max: { queenCycleGapMs: 30 * 1e3, queenMaxTurns: 30 },
11321
- // 30s gap, 30 turns
11322
- api: { queenCycleGapMs: 2 * 60 * 1e3, queenMaxTurns: 30 }
11323
- // 2 min gap, 30 turns
11317
+ none: { queenCycleGapMs: 10 * 60 * 1e3, queenMaxTurns: 50 },
11318
+ // 10 min gap, 50 turns
11319
+ pro: { queenCycleGapMs: 5 * 60 * 1e3, queenMaxTurns: 50 },
11320
+ // 5 min gap, 50 turns
11321
+ max: { queenCycleGapMs: 30 * 1e3, queenMaxTurns: 50 },
11322
+ // 30s gap, 50 turns
11323
+ api: { queenCycleGapMs: 2 * 60 * 1e3, queenMaxTurns: 50 }
11324
+ // 2 min gap, 50 turns
11324
11325
  };
11325
11326
  var CHATGPT_DEFAULTS_BY_PLAN = {
11326
- none: { queenCycleGapMs: 10 * 60 * 1e3, queenMaxTurns: 30 },
11327
- // 10 min gap, 30 turns
11328
- plus: { queenCycleGapMs: 5 * 60 * 1e3, queenMaxTurns: 30 },
11329
- // 5 min gap, 30 turns
11330
- pro: { queenCycleGapMs: 2 * 60 * 1e3, queenMaxTurns: 30 },
11331
- // 2 min gap, 30 turns
11332
- api: { queenCycleGapMs: 2 * 60 * 1e3, queenMaxTurns: 30 }
11333
- // 2 min gap, 30 turns
11327
+ none: { queenCycleGapMs: 10 * 60 * 1e3, queenMaxTurns: 50 },
11328
+ // 10 min gap, 50 turns
11329
+ plus: { queenCycleGapMs: 5 * 60 * 1e3, queenMaxTurns: 50 },
11330
+ // 5 min gap, 50 turns
11331
+ pro: { queenCycleGapMs: 2 * 60 * 1e3, queenMaxTurns: 50 },
11332
+ // 2 min gap, 50 turns
11333
+ api: { queenCycleGapMs: 2 * 60 * 1e3, queenMaxTurns: 50 }
11334
+ // 2 min gap, 50 turns
11334
11335
  };
11335
11336
  var WORKER_ROLE_PRESETS = {
11336
11337
  guardian: {
@@ -12200,7 +12201,7 @@ function mapRoomRow(row) {
12200
12201
  maxConcurrentTasks: row.max_concurrent_tasks ?? 3,
12201
12202
  workerModel: row.worker_model ?? "claude",
12202
12203
  queenCycleGapMs: row.queen_cycle_gap_ms ?? 18e5,
12203
- queenMaxTurns: row.queen_max_turns ?? 3,
12204
+ queenMaxTurns: row.queen_max_turns ?? 50,
12204
12205
  queenQuietFrom: row.queen_quiet_from ?? null,
12205
12206
  queenQuietUntil: row.queen_quiet_until ?? null,
12206
12207
  config,
@@ -31903,7 +31904,7 @@ CREATE TABLE IF NOT EXISTS rooms (
31903
31904
  max_concurrent_tasks INTEGER NOT NULL DEFAULT 3,
31904
31905
  worker_model TEXT NOT NULL DEFAULT 'claude',
31905
31906
  queen_cycle_gap_ms INTEGER NOT NULL DEFAULT 1800000,
31906
- queen_max_turns INTEGER NOT NULL DEFAULT 3,
31907
+ queen_max_turns INTEGER NOT NULL DEFAULT 50,
31907
31908
  queen_quiet_from TEXT,
31908
31909
  queen_quiet_until TEXT,
31909
31910
  config TEXT,
@@ -32357,6 +32358,10 @@ function upsertSetting(database, key, value) {
32357
32358
  }
32358
32359
  function runMigrations(database, log = console.log) {
32359
32360
  database.exec(SCHEMA);
32361
+ const legacyQueenTurnsUpdated = database.prepare(`UPDATE rooms SET queen_max_turns = 50 WHERE queen_max_turns = 3`).run().changes;
32362
+ if (legacyQueenTurnsUpdated > 0) {
32363
+ log(`Migrated: updated ${legacyQueenTurnsUpdated} room(s) queen_max_turns from 3 to 50`);
32364
+ }
32360
32365
  if (!database.prepare("SELECT value FROM settings WHERE key = ?").get("keeper_referral_code")) {
32361
32366
  const code = (0, import_crypto10.randomBytes)(6).toString("base64url").slice(0, 10);
32362
32367
  upsertSetting(database, "keeper_referral_code", code);
@@ -32672,7 +32677,7 @@ function semverGt(a, b) {
32672
32677
  }
32673
32678
  function getCurrentVersion() {
32674
32679
  try {
32675
- return true ? "0.1.39" : null.version;
32680
+ return true ? "0.1.40" : null.version;
32676
32681
  } catch {
32677
32682
  return "0.0.0";
32678
32683
  }
@@ -32727,7 +32732,7 @@ async function checkAndApplyUpdate(bundleUrl, targetVersion) {
32727
32732
  }
32728
32733
 
32729
32734
  // src/server/updateChecker.ts
32730
- var CHECK_INTERVAL = 4 * 60 * 60 * 1e3;
32735
+ var DEFAULT_CHECK_INTERVAL = 4 * 60 * 60 * 1e3;
32731
32736
  var INITIAL_DELAY = 15e3;
32732
32737
  var cached = null;
32733
32738
  var initTimer = null;
@@ -32785,7 +32790,7 @@ function fetchJson(url) {
32785
32790
  });
32786
32791
  });
32787
32792
  }
32788
- async function forceCheck() {
32793
+ async function forceCheck(options = {}) {
32789
32794
  try {
32790
32795
  const releases = await fetchJson(
32791
32796
  "https://api.github.com/repos/quoroom-ai/room/releases?per_page=100"
@@ -32805,19 +32810,28 @@ async function forceCheck() {
32805
32810
  }
32806
32811
  cached = { latestVersion, releaseUrl: latest.html_url, assets, updateBundle };
32807
32812
  if (updateBundle && latestVersion) {
32808
- void checkAndApplyUpdate(updateBundle, latestVersion).catch(() => {
32813
+ const beforeReadyVersion = getReadyUpdateVersion();
32814
+ await checkAndApplyUpdate(updateBundle, latestVersion).catch(() => {
32809
32815
  });
32816
+ const afterReadyVersion = getReadyUpdateVersion();
32817
+ if (options.onReadyUpdate && afterReadyVersion && afterReadyVersion !== beforeReadyVersion) {
32818
+ try {
32819
+ options.onReadyUpdate(afterReadyVersion);
32820
+ } catch {
32821
+ }
32822
+ }
32810
32823
  }
32811
32824
  } catch {
32812
32825
  }
32813
32826
  }
32814
- function initUpdateChecker() {
32827
+ function initUpdateChecker(options = {}) {
32815
32828
  if (process.env.NODE_ENV === "test") return;
32829
+ const pollEvery = Number.isFinite(options.pollIntervalMs) && (options.pollIntervalMs ?? 0) > 0 ? Number(options.pollIntervalMs) : DEFAULT_CHECK_INTERVAL;
32816
32830
  initTimer = setTimeout(() => {
32817
- void forceCheck();
32831
+ void forceCheck({ onReadyUpdate: options.onReadyUpdate });
32818
32832
  pollInterval = setInterval(() => {
32819
- void forceCheck();
32820
- }, CHECK_INTERVAL);
32833
+ void forceCheck({ onReadyUpdate: options.onReadyUpdate });
32834
+ }, pollEvery);
32821
32835
  }, INITIAL_DELAY);
32822
32836
  }
32823
32837
  function stopUpdateChecker() {
@@ -32853,7 +32867,7 @@ var cachedVersion = null;
32853
32867
  function getVersion3() {
32854
32868
  if (cachedVersion) return cachedVersion;
32855
32869
  try {
32856
- cachedVersion = true ? "0.1.39" : null.version;
32870
+ cachedVersion = true ? "0.1.40" : null.version;
32857
32871
  } catch {
32858
32872
  cachedVersion = "unknown";
32859
32873
  }
@@ -34758,6 +34772,17 @@ function scheduleSelfRestart() {
34758
34772
  return false;
34759
34773
  }
34760
34774
  }
34775
+ function createCloudReadyUpdateHandler(triggerShutdown) {
34776
+ let queued = false;
34777
+ return (version5) => {
34778
+ if (queued) return;
34779
+ queued = true;
34780
+ console.error(`[auto-update] Cloud update v${version5} is ready. Restarting to apply.`);
34781
+ setTimeout(() => {
34782
+ triggerShutdown();
34783
+ }, 120);
34784
+ };
34785
+ }
34761
34786
  var MIME_TYPES = {
34762
34787
  ".html": "text/html; charset=utf-8",
34763
34788
  ".js": "application/javascript; charset=utf-8",
@@ -35055,6 +35080,13 @@ function createApiServer(options = {}) {
35055
35080
  }
35056
35081
  const role = principal.role;
35057
35082
  if (pathname === "/api/status/update/download" && req.method === "GET") {
35083
+ if (isCloudDeployment()) {
35084
+ res.writeHead(409, responseHeaders);
35085
+ res.end(JSON.stringify({
35086
+ error: "Installer download is disabled in cloud deployment. Updates are applied automatically."
35087
+ }));
35088
+ return;
35089
+ }
35058
35090
  if (!isAllowedForRole(role, req.method, pathname, db2)) {
35059
35091
  res.writeHead(403, responseHeaders);
35060
35092
  res.end(JSON.stringify({ error: "Forbidden" }));
@@ -35247,7 +35279,18 @@ function startServer(options = {}) {
35247
35279
  });
35248
35280
  }
35249
35281
  initCloudSync(serverDb);
35250
- initUpdateChecker();
35282
+ if (deploymentMode === "cloud") {
35283
+ const onReadyUpdate = createCloudReadyUpdateHandler(() => {
35284
+ if (requestProcessShutdown) requestProcessShutdown();
35285
+ else process.exit(0);
35286
+ });
35287
+ initUpdateChecker({
35288
+ pollIntervalMs: 15 * 60 * 1e3,
35289
+ onReadyUpdate
35290
+ });
35291
+ } else {
35292
+ initUpdateChecker();
35293
+ }
35251
35294
  startServerRuntime(serverDb);
35252
35295
  function listen() {
35253
35296
  server.listen(port, bindHost, () => {
@@ -35330,6 +35373,7 @@ function startServer(options = {}) {
35330
35373
  }
35331
35374
  // Annotate the CommonJS export names for ESM import in node:
35332
35375
  0 && (module.exports = {
35376
+ _createCloudReadyUpdateHandler,
35333
35377
  _isLoopbackAddress,
35334
35378
  _resolveStaticDirForStart,
35335
35379
  _shellQuote,