eve-hub 0.6.26 → 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.
- package/CHANGELOG.md +12 -0
- package/package.json +1 -1
- package/world.mjs +67 -29
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
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
|
+
|
|
9
|
+
## 0.6.27
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- Hosted hub: organisation writes (rename, move, merge, file) are conditional batches that answer 409 when a fact they were built from changed.
|
|
14
|
+
|
|
3
15
|
## 0.6.26
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eve-hub",
|
|
3
|
-
"version": "0.6.
|
|
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
|
@@ -100,8 +100,8 @@ function briefLabel(text, { strict = false } = {}) {
|
|
|
100
100
|
}
|
|
101
101
|
function title(action, label) {
|
|
102
102
|
const name = action.toolName ?? action.name ?? "task";
|
|
103
|
-
const
|
|
104
|
-
if (
|
|
103
|
+
const labelled2 = label ? briefLabel(clean(label), { strict: true }) : void 0;
|
|
104
|
+
if (labelled2) return truncate(labelled2, MAX_TITLE);
|
|
105
105
|
const asked = briefLabel(agentBrief(action.input));
|
|
106
106
|
return asked ? truncate(asked, MAX_TITLE) : name;
|
|
107
107
|
}
|
|
@@ -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
|
|
467
|
-
|
|
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");
|