eve-hub 0.6.27 → 0.6.28

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.
Files changed (3) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/package.json +1 -1
  3. package/world.mjs +65 -27
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # eve-hub
2
2
 
3
+ ## 0.6.28
4
+
5
+ ### Patch Changes
6
+
7
+ - The hosted bots' world carries the hub's message-fact folding: a reviewer's verdict, a turn's task card and event rows are kept.
8
+
3
9
  ## 0.6.27
4
10
 
5
11
  ### Patch Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eve-hub",
3
- "version": "0.6.27",
3
+ "version": "0.6.28",
4
4
  "license": "Apache-2.0",
5
5
  "description": "Bot-side code shared by every hub agent: registry tools, the roster hook, the eve channel, the host sandbox and browser, and model helpers.",
6
6
  "type": "module",
package/world.mjs CHANGED
@@ -417,30 +417,6 @@ function reduceChild(member, { type, data = {}, meta: meta4 }, at = Date.parse(m
417
417
  import { createClient } from "@libsql/client";
418
418
  var s = (sql, ...args) => ({ sql, args });
419
419
 
420
- // subagent-cap.mjs
421
- var DEFAULT_SUBAGENT_CAP = Object.freeze({
422
- model: "anthropic/claude-fable-5.1",
423
- reasoning: "low",
424
- models: Object.freeze(["anthropic/claude-fable-5.1"])
425
- });
426
-
427
- // ../../hosted-hub/src/store/schema.ts
428
- var OPEN_TURN_STATUSES = "('streaming','cancelling')";
429
-
430
- // ../../hosted-hub/src/domain/wake.ts
431
- var escape = (s2) => s2.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
432
- var mentioned = (roster, text) => roster.filter((bot) => new RegExp(`(^|[^\\w@])@${escape(bot)}(?![\\w-])`, "i").test(text));
433
- var hasAll = (text) => /(^|[^\w@])@all(?![\w-])/i.test(text);
434
- function recipients(roster, text, from, threadId2 = "", participants = []) {
435
- if (threadId2.startsWith("dm-")) {
436
- const bot = threadId2.slice(3);
437
- return bot !== from.name && roster.includes(bot) ? [bot] : [];
438
- }
439
- const named = [.../* @__PURE__ */ new Set([...mentioned(roster, text), ...hasAll(text) ? participants.filter((b) => roster.includes(b)) : []])].filter((bot) => bot !== from.name);
440
- if (from.kind === "agent") return named;
441
- return named.length ? named : roster.slice(0, 1);
442
- }
443
-
444
420
  // ../../hosted-hub/src/domain/ids.ts
445
421
  import { createHash, randomBytes } from "node:crypto";
446
422
  var alphabet = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
@@ -455,6 +431,7 @@ function base32(value) {
455
431
  function ulid(now = Date.now()) {
456
432
  return base32(BigInt(now) << 80n | BigInt(`0x${randomBytes(10).toString("hex")}`));
457
433
  }
434
+ var eventId = () => `evt_${ulid()}`;
458
435
  function derivedMessageId(...parts) {
459
436
  return `msg_${base32(BigInt(`0x${createHash("sha256").update(parts.join("\0")).digest("hex").slice(0, 33)}`) >> 2n)}`;
460
437
  }
@@ -462,12 +439,45 @@ var sessionId = () => `wrun_${ulid()}`;
462
439
  var deliveryId = (message, bot) => `dlv_${message}_${bot}`;
463
440
  var turnId = (session, chunkIndex) => `trn_${session}_${chunkIndex}`;
464
441
 
442
+ // ../../hosted-hub/src/store/events.ts
443
+ function eventStatements(threadId2, event, text, at, id = eventId(), only) {
444
+ return [
445
+ s(
446
+ `INSERT OR IGNORE INTO messages (id, thread_id, author, author_kind, text, created_at, event) SELECT ?, ?, 'system', 'event', ?, ?, ? WHERE ${only?.sql ?? "1"}`,
447
+ id,
448
+ threadId2,
449
+ text,
450
+ at,
451
+ JSON.stringify(event),
452
+ ...only?.args ?? []
453
+ ),
454
+ s(`INSERT INTO log (thread_id,type,data,at) SELECT ?, 'message.created', ?, ? WHERE changes() > 0`, threadId2, JSON.stringify({ threadId: threadId2, messageId: id, author: "system", authorKind: "event" }), at)
455
+ ];
456
+ }
457
+
465
458
  // ../../hosted-hub/src/store/routing.ts
466
- var PARTICIPANTS = (thread) => `SELECT bot FROM sessions WHERE thread_id = ${thread} UNION SELECT author FROM messages WHERE thread_id = ${thread} AND author_kind = 'agent'`;
467
- function routingStatements(messageId2, threadId2, bots, now, held = {}, steer = false) {
459
+ var THREAD_REFS = 3;
460
+ var threadArgs = (threadId2, ...rest) => [...Array(THREAD_REFS).fill(threadId2), ...rest];
461
+ var PARTICIPANTS = (thread, except = "''") => `SELECT DISTINCT p.bot FROM (
462
+ SELECT thread_id AS tid, bot, created_at AS at, NULL AS mid FROM sessions WHERE thread_id = ${thread}
463
+ UNION ALL SELECT thread_id, author, created_at, id FROM messages WHERE thread_id = ${thread} AND author_kind = 'agent'
464
+ UNION ALL SELECT thread_id, json_extract(event, '$.agent'), created_at, id FROM messages WHERE thread_id = ${thread} AND author_kind = 'event' AND json_extract(event, '$.kind') = 'join') p
465
+ WHERE p.mid IS NOT ${except} AND p.at > COALESCE((SELECT MAX(l.created_at) FROM messages l WHERE l.thread_id = p.tid AND l.author_kind = 'event'
466
+ AND json_extract(l.event, '$.kind') = 'leave' AND json_extract(l.event, '$.agent') = p.bot), -1)`;
467
+ var hasJoins = (threadId2) => !threadId2.startsWith("dm-") && !threadId2.startsWith("sch-");
468
+ function routingStatements(messageId2, threadId2, bots, now, { by, joins }, held = {}, steer = false) {
469
+ const quiet = !joins || !hasJoins(threadId2);
468
470
  const fresh = "EXISTS (SELECT 1 FROM messages WHERE id = ?)";
469
471
  return [
470
472
  ...bots.flatMap((bot) => [
473
+ ...quiet ? [] : eventStatements(
474
+ threadId2,
475
+ { kind: "join", agent: bot, by, message: messageId2 },
476
+ `@${bot} joined${by !== bot ? ` (added by @${by})` : ""}`,
477
+ now,
478
+ eventId(),
479
+ s(`${fresh} AND NOT EXISTS (SELECT 1 FROM (${PARTICIPANTS("?")}) WHERE bot = ?)`, messageId2, ...threadArgs(threadId2), bot)
480
+ ),
471
481
  s(`INSERT OR IGNORE INTO sessions (id,thread_id,bot,created_at) SELECT ?,?,?,? WHERE ${fresh}`, sessionId(), threadId2, bot, now, messageId2),
472
482
  s(
473
483
  `INSERT OR IGNORE INTO deliveries (id,message_id,bot,session_id,created_at)
@@ -486,6 +496,30 @@ function routingStatements(messageId2, threadId2, bots, now, held = {}, steer =
486
496
  ];
487
497
  }
488
498
 
499
+ // subagent-cap.mjs
500
+ var DEFAULT_SUBAGENT_CAP = Object.freeze({
501
+ model: "anthropic/claude-fable-5.1",
502
+ reasoning: "low",
503
+ models: Object.freeze(["anthropic/claude-fable-5.1"])
504
+ });
505
+
506
+ // ../../hosted-hub/src/store/schema.ts
507
+ var OPEN_TURN_STATUSES = "('streaming','cancelling')";
508
+
509
+ // ../../hosted-hub/src/domain/wake.ts
510
+ var escape = (s2) => s2.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
511
+ var mentioned = (roster, text) => roster.filter((bot) => new RegExp(`(^|[^\\w@])@${escape(bot)}(?![\\w-])`, "i").test(text));
512
+ var hasAll = (text) => /(^|[^\w@])@all(?![\w-])/i.test(text);
513
+ function recipients(roster, text, from, threadId2 = "", participants = []) {
514
+ if (threadId2.startsWith("dm-")) {
515
+ const bot = threadId2.slice(3);
516
+ return bot !== from.name && roster.includes(bot) ? [bot] : [];
517
+ }
518
+ const named = [.../* @__PURE__ */ new Set([...mentioned(roster, text), ...hasAll(text) ? participants.filter((b) => roster.includes(b)) : []])].filter((bot) => bot !== from.name);
519
+ if (from.kind === "agent") return named;
520
+ return named.length ? named : roster.slice(0, 1);
521
+ }
522
+
489
523
  // ../../lib/usage.mjs
490
524
  var emptyBucket = () => ({ steps: 0, inputTokens: 0, outputTokens: 0, cacheReadTokens: 0, cacheWriteTokens: 0, costUsd: null, unpricedSteps: 0 });
491
525
  var TOKENS = ["inputTokens", "outputTokens", "cacheReadTokens", "cacheWriteTokens"];
@@ -26961,6 +26995,10 @@ var SESSION_WORK_DELIVERY = `busy.accepted_at IS NOT NULL AND busy.failed_at IS
26961
26995
  WHERE td.delivery_id = busy.id AND t.status NOT IN ('streaming','cancelling'))`;
26962
26996
  var SESSION_BUSY = `s.ended_at IS NULL AND EXISTS (SELECT 1 FROM deliveries busy
26963
26997
  WHERE busy.session_id = s.id AND ${SESSION_WORK_DELIVERY})`;
26998
+ var TASK_CARD = `(SELECT CASE WHEN json_array_length(json_extract(t.activity, '$.taskCard.tasks')) > 0 THEN json_extract(t.activity, '$.taskCard') END
26999
+ FROM turns t WHERE t.id = m.turn_id AND m.author_kind = 'agent' AND t.status NOT IN ${OPEN_TURN_STATUSES}
27000
+ AND m.rowid = (SELECT MAX(x.rowid) FROM messages x WHERE x.turn_id = m.turn_id))`;
27001
+ var FACT_COLUMNS = `status, status_from, metadata, verdict, decisions, tested, ${TASK_CARD} AS task_card, event`;
26964
27002
  var LINKED = "EXISTS (SELECT 1 FROM turn_deliveries td WHERE td.delivery_id = d.id)";
26965
27003
  var DELIVERY_STATUS = `CASE WHEN d.accepted_at IS NOT NULL OR ${LINKED} THEN COALESCE((SELECT 'waiting: on your answer to its ' || r.kind || ' request'
26966
27004
  FROM input_requests r JOIN sessions rs ON rs.id = r.session_id
@@ -27115,7 +27153,7 @@ function fold(state, chunks, now = Date.now()) {
27115
27153
  AND EXISTS (SELECT 1 FROM turns WHERE id = ? AND status NOT IN ('cancelling','cancelled') AND NOT (${REVOKED_TURN}))`, messageId2, session.thread, session.bot, text, open3.id, at, text, open3.id));
27116
27154
  log("message.created", { messageId: messageId2, author: session.bot, authorKind: "agent" }, IF_INSERTED);
27117
27155
  const to = recipients(state.roster, text, { name: session.bot, kind: "agent" }, session.thread, state.participants);
27118
- stmts.push(...routingStatements(messageId2, session.thread, to, at));
27156
+ stmts.push(...routingStatements(messageId2, session.thread, to, at, { by: session.bot, joins: true }));
27119
27157
  deliver.push(messageId2);
27120
27158
  }
27121
27159
  end("done");