eve-hub 0.6.31 → 0.6.33
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/image-limits.d.mts +5 -0
- package/mention-tokens.d.mts +1 -0
- package/mention-tokens.mjs +15 -0
- package/package.json +1 -1
- package/schedules/compact.js +2 -1
- package/schedules/dash.js +2 -1
- package/schedules/hub.d.mts +2 -1
- package/schedules/hub.mjs +27 -3
- package/tools/view_image.d.ts +6 -6
- package/world.mjs +115 -21
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# eve-hub
|
|
2
2
|
|
|
3
|
+
## 0.6.33
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Hosted hub: a schedule's run history is what its handler reports (hub.track: a start, an end and the error), so a dispatch is one run however often it loads state; a commit names its run. The mention rule moves to the kit (mention-tokens.mjs).
|
|
8
|
+
|
|
9
|
+
## 0.6.32
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- The hosted bots' world carries the hub's image attachments: uploads are stored and handed to bots with a message.
|
|
14
|
+
|
|
3
15
|
## 0.6.31
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export const MAX_BYTES: number;
|
|
2
|
+
export const MODEL_MAX_EDGE: number;
|
|
3
|
+
export function sniffImage(bytes: Uint8Array): string | null;
|
|
4
|
+
export function imageSize(bytes: Uint8Array, mediaType: string): { width: number; height: number } | null;
|
|
5
|
+
export function modelUnsafe(bytes: Uint8Array): string | null;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export function mentionTokens(text: unknown): string[];
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { codeRanges } from "./mention-gate.mjs";
|
|
2
|
+
|
|
3
|
+
// The one definition of an actual mention: `@handle` at a word boundary (not
|
|
4
|
+
// foo@bar, @@x, \@x or a URL's /@x) and outside code (codeRanges). Every reader of
|
|
5
|
+
// handles (routing, aliases, @all, notifications) takes its tokens from here; anything else
|
|
6
|
+
// is text. Returns the lowercased handles in order, duplicates kept.
|
|
7
|
+
export function mentionTokens(text) {
|
|
8
|
+
const s = String(text ?? "");
|
|
9
|
+
const code = codeRanges(s);
|
|
10
|
+
const out = [];
|
|
11
|
+
for (const match of s.matchAll(/(?<![\w@./\\-])@([a-z0-9][a-z0-9-]*)/gi)) {
|
|
12
|
+
if (!code.some(([a, b]) => match.index >= a && match.index < b)) out.push(match[1].toLowerCase());
|
|
13
|
+
}
|
|
14
|
+
return out;
|
|
15
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eve-hub",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.33",
|
|
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/schedules/compact.js
CHANGED
package/schedules/dash.js
CHANGED
|
@@ -15,6 +15,7 @@ import { modelSummarize } from "./track-summaries.mjs";
|
|
|
15
15
|
export default defineSchedule({
|
|
16
16
|
cron: "*/8 * * * *",
|
|
17
17
|
async run() {
|
|
18
|
-
|
|
18
|
+
const hub = createHub();
|
|
19
|
+
await hub.track("dash", () => dashPass(hub, { classify: modelClassify({ evaluate }), summarize: modelSummarize({ generateText }) }));
|
|
19
20
|
},
|
|
20
21
|
});
|
package/schedules/hub.d.mts
CHANGED
|
@@ -9,10 +9,11 @@ export type Hub = {
|
|
|
9
9
|
snapshot(): Promise<Record<string, unknown>>;
|
|
10
10
|
roster(): Promise<unknown>;
|
|
11
11
|
load(id: string): Promise<unknown>;
|
|
12
|
-
loadVersioned(id: string): Promise<{ state: unknown; savedAt: string | null }>;
|
|
12
|
+
loadVersioned(id: string): Promise<{ state: unknown; savedAt: string | null; paused: boolean }>;
|
|
13
13
|
save(id: string, state: unknown): Promise<unknown>;
|
|
14
14
|
commit(id: string, withState: { state?: unknown }, posts: Post[]): Promise<unknown>;
|
|
15
15
|
post(id: string, text: string, key?: string): Promise<unknown>;
|
|
16
|
+
track<T>(id: string, fn: () => Promise<T>): Promise<T | undefined>;
|
|
16
17
|
compact(threadId: string, bot: string, by: string, report?: { trigger?: string; reportTo?: string }): Promise<{ status: number; ok: boolean; body: unknown }>;
|
|
17
18
|
dashChecked(prFacts?: Record<string, { head: string | null; ci: string }>): Promise<Ok & { checkedAt: string }>;
|
|
18
19
|
setSummary(path: string, text: string): Promise<unknown>;
|
package/schedules/hub.mjs
CHANGED
|
@@ -23,6 +23,8 @@ export function createHub({ base = registryBase(), agent = "main", fetchImpl = f
|
|
|
23
23
|
if (!r.ok) throw new Error(`${init?.method ?? "GET"} ${path}: ${r.status} ${typeof r.body === "string" ? r.body : JSON.stringify(r.body)}`.slice(0, 400));
|
|
24
24
|
return r.body;
|
|
25
25
|
};
|
|
26
|
+
// The run the hub is following for this process's handler (`track`), so a commit says which run it belongs to.
|
|
27
|
+
let run = null;
|
|
26
28
|
const threadOf = (id) => `sch-${agent}-${id.replaceAll("/", ".")}`;
|
|
27
29
|
const statePath = (id) => `/api/schedules/${encodeURIComponent(agent)}/${id.split("/").map(encodeURIComponent).join("/")}/state`;
|
|
28
30
|
return {
|
|
@@ -32,11 +34,31 @@ export function createHub({ base = registryBase(), agent = "main", fetchImpl = f
|
|
|
32
34
|
// The state and when it was saved (the version a run decided on).
|
|
33
35
|
loadVersioned: async (id) => {
|
|
34
36
|
const body = await must(statePath(id));
|
|
35
|
-
return { state: body?.state ?? null, savedAt: body?.savedAt ?? null };
|
|
37
|
+
return { state: body?.state ?? null, savedAt: body?.savedAt ?? null, paused: body?.paused === true };
|
|
36
38
|
},
|
|
37
39
|
save: (id, state) => must(statePath(id), { method: "PUT", body: JSON.stringify({ state }) }),
|
|
38
40
|
// Save `state` (if given: { state }) and post `posts` in one step.
|
|
39
|
-
commit: (id, withState, posts) => must(statePath(id), { method: "PUT", body: JSON.stringify({ ...withState, posts }) }),
|
|
41
|
+
commit: (id, withState, posts) => must(statePath(id), { method: "PUT", body: JSON.stringify({ ...withState, posts, ...(run?.id === id ? { run: run.run } : {}) }) }),
|
|
42
|
+
// One dispatch of the schedule `id`: the hub is told it started (it answers with the run's id and whether the
|
|
43
|
+
// schedule is paused, which skips `fn`) and how it ended, so the hub's run history is what the handler did. A hub
|
|
44
|
+
// that doesn't keep run history (the local one) answers 404 to the start, and `fn` runs untracked.
|
|
45
|
+
track: async (id, fn) => {
|
|
46
|
+
const started = await call(`${statePath(id).slice(0, -"/state".length)}/runs`, { method: "POST", body: "{}" }).catch(() => null);
|
|
47
|
+
if (!started?.ok) return fn();
|
|
48
|
+
if (started.body.paused) return;
|
|
49
|
+
run = { id, run: started.body.run };
|
|
50
|
+
const end = (error) => call(`${statePath(id).slice(0, -"/state".length)}/runs/${encodeURIComponent(run.run)}/end`, { method: "POST", body: JSON.stringify(error ? { error: error.slice(0, 2000) } : {}) }).catch(() => null);
|
|
51
|
+
try {
|
|
52
|
+
const result = await fn();
|
|
53
|
+
await end();
|
|
54
|
+
return result;
|
|
55
|
+
} catch (error) {
|
|
56
|
+
await end(String(error?.message ?? error) || "the run failed");
|
|
57
|
+
throw error;
|
|
58
|
+
} finally {
|
|
59
|
+
run = null;
|
|
60
|
+
}
|
|
61
|
+
},
|
|
40
62
|
// A one-off post outside a run (runOnce commits through `commit`).
|
|
41
63
|
post: (id, text, key) => must(`/api/threads/${encodeURIComponent(threadOf(id))}/messages`, { method: "POST", body: JSON.stringify({ author: "system", text, ...(key ? { clientId: key } : {}) }) }),
|
|
42
64
|
// With `report` ({ trigger, reportTo: "<bot>/<schedule>" }) the hub posts
|
|
@@ -117,10 +139,12 @@ export function toPosts(notices) {
|
|
|
117
139
|
// the same keys and the hub skips the posts it already has. Nothing is
|
|
118
140
|
// lost and nothing posted twice. `decide(snap, saved, now)` ->
|
|
119
141
|
// { posts: [text], state, changed }; `snapshot: false` skips reading
|
|
120
|
-
// /api/state (decide gets null).
|
|
142
|
+
// /api/state (decide gets null). A paused schedule (the state's `paused`)
|
|
143
|
+
// decides and commits nothing.
|
|
121
144
|
export async function runOnce(hub, id, decide, { now = Date.now(), snapshot = true } = {}) {
|
|
122
145
|
const [snap, loaded] = await Promise.all([snapshot ? hub.snapshot() : null, hub.loadVersioned(id)]);
|
|
123
146
|
const saved = loaded.state;
|
|
147
|
+
if (loaded.paused) return { posts: [], state: saved };
|
|
124
148
|
const { posts = [], state, changed } = await decide(snap, saved, now);
|
|
125
149
|
const texts = toPosts(posts.filter((t) => typeof t === "string" && t.trim()));
|
|
126
150
|
if (!changed && !texts.length) return { posts: [], state: saved };
|
package/tools/view_image.d.ts
CHANGED
|
@@ -13,7 +13,7 @@ export declare function prepareImage(bytes: Uint8Array, name: string, { resize }
|
|
|
13
13
|
resize?: Resize;
|
|
14
14
|
}): Promise<{
|
|
15
15
|
name: string;
|
|
16
|
-
mediaType:
|
|
16
|
+
mediaType: string;
|
|
17
17
|
original: string | undefined;
|
|
18
18
|
unsafe: string;
|
|
19
19
|
data?: undefined;
|
|
@@ -23,7 +23,7 @@ export declare function prepareImage(bytes: Uint8Array, name: string, { resize }
|
|
|
23
23
|
unsafe?: undefined;
|
|
24
24
|
data: string;
|
|
25
25
|
name: string;
|
|
26
|
-
mediaType:
|
|
26
|
+
mediaType: string;
|
|
27
27
|
bytes: number;
|
|
28
28
|
original: string | undefined;
|
|
29
29
|
shown: string | undefined;
|
|
@@ -35,7 +35,7 @@ declare const _default: import("eve/tools").ToolDefinition<{
|
|
|
35
35
|
screenshot?: boolean | undefined;
|
|
36
36
|
}, {
|
|
37
37
|
name: string;
|
|
38
|
-
mediaType:
|
|
38
|
+
mediaType: string;
|
|
39
39
|
original: string | undefined;
|
|
40
40
|
unsafe: string;
|
|
41
41
|
data?: undefined;
|
|
@@ -45,7 +45,7 @@ declare const _default: import("eve/tools").ToolDefinition<{
|
|
|
45
45
|
unsafe?: undefined;
|
|
46
46
|
data: string;
|
|
47
47
|
name: string;
|
|
48
|
-
mediaType:
|
|
48
|
+
mediaType: string;
|
|
49
49
|
bytes: number;
|
|
50
50
|
original: string | undefined;
|
|
51
51
|
shown: string | undefined;
|
|
@@ -55,7 +55,7 @@ declare const _default: import("eve/tools").ToolDefinition<{
|
|
|
55
55
|
screenshot?: boolean | undefined;
|
|
56
56
|
}, ctx: import("eve/tools").ToolContext): Promise<{
|
|
57
57
|
name: string;
|
|
58
|
-
mediaType:
|
|
58
|
+
mediaType: string;
|
|
59
59
|
original: string | undefined;
|
|
60
60
|
unsafe: string;
|
|
61
61
|
data?: undefined;
|
|
@@ -65,7 +65,7 @@ declare const _default: import("eve/tools").ToolDefinition<{
|
|
|
65
65
|
unsafe?: undefined;
|
|
66
66
|
data: string;
|
|
67
67
|
name: string;
|
|
68
|
-
mediaType:
|
|
68
|
+
mediaType: string;
|
|
69
69
|
bytes: number;
|
|
70
70
|
original: string | undefined;
|
|
71
71
|
shown: string | undefined;
|
package/world.mjs
CHANGED
|
@@ -545,6 +545,79 @@ function stepValues(sessionId2, step) {
|
|
|
545
545
|
return [sessionId2, step.sequence, step.stepIndex, Date.parse(step.at), b.inputTokens, b.outputTokens, b.cacheReadTokens, b.cacheWriteTokens, b.costUsd];
|
|
546
546
|
}
|
|
547
547
|
|
|
548
|
+
// mention-gate.mjs
|
|
549
|
+
function codeRanges(text) {
|
|
550
|
+
const s2 = String(text ?? "");
|
|
551
|
+
const ranges = [];
|
|
552
|
+
const lines = [];
|
|
553
|
+
for (let at = 0; at <= s2.length; ) {
|
|
554
|
+
const nl = s2.indexOf("\n", at);
|
|
555
|
+
const end = nl < 0 ? s2.length : nl;
|
|
556
|
+
lines.push({ start: at, end, text: s2.slice(at, end) });
|
|
557
|
+
if (nl < 0) break;
|
|
558
|
+
at = nl + 1;
|
|
559
|
+
}
|
|
560
|
+
const fenced = /* @__PURE__ */ new Set();
|
|
561
|
+
for (let i = 0; i < lines.length; i++) {
|
|
562
|
+
const open3 = lines[i].text.match(/^ {0,3}(`{3,}|~{3,})(.*)$/);
|
|
563
|
+
if (!open3 || open3[1][0] === "`" && open3[2].includes("`")) continue;
|
|
564
|
+
const close = new RegExp(`^ {0,3}${open3[1][0] === "`" ? "`" : "~"}{${open3[1].length},}\\s*$`);
|
|
565
|
+
const j = lines.findIndex((l, k) => k > i && close.test(l.text));
|
|
566
|
+
if (j < 0) continue;
|
|
567
|
+
ranges.push([lines[i].start, lines[j].end]);
|
|
568
|
+
for (let k = i; k <= j; k++) fenced.add(k);
|
|
569
|
+
i = j;
|
|
570
|
+
}
|
|
571
|
+
let para = [];
|
|
572
|
+
const flush = () => {
|
|
573
|
+
if (!para.length) return;
|
|
574
|
+
const from = para[0].start;
|
|
575
|
+
const t = s2.slice(from, para.at(-1).end);
|
|
576
|
+
const runs = [...t.matchAll(/`+/g)].map((m) => ({ at: m.index, n: m[0].length }));
|
|
577
|
+
for (let i = 0; i < runs.length; i++) {
|
|
578
|
+
let { at, n } = runs[i];
|
|
579
|
+
let slash = 0;
|
|
580
|
+
for (let b = at - 1; b >= 0 && t[b] === "\\"; b--) slash++;
|
|
581
|
+
if (slash % 2 === 1) {
|
|
582
|
+
at++;
|
|
583
|
+
n--;
|
|
584
|
+
if (!n) continue;
|
|
585
|
+
}
|
|
586
|
+
const j = runs.findIndex((r, k) => k > i && r.n === n);
|
|
587
|
+
if (j < 0) continue;
|
|
588
|
+
ranges.push([from + at, from + runs[j].at + n]);
|
|
589
|
+
i = j;
|
|
590
|
+
}
|
|
591
|
+
para = [];
|
|
592
|
+
};
|
|
593
|
+
lines.forEach((l, i) => {
|
|
594
|
+
if (!fenced.has(i) && l.text.trim()) para.push(l);
|
|
595
|
+
flush();
|
|
596
|
+
});
|
|
597
|
+
return ranges;
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
// mention-tokens.mjs
|
|
601
|
+
function mentionTokens(text) {
|
|
602
|
+
const s2 = String(text ?? "");
|
|
603
|
+
const code = codeRanges(s2);
|
|
604
|
+
const out = [];
|
|
605
|
+
for (const match of s2.matchAll(/(?<![\w@./\\-])@([a-z0-9][a-z0-9-]*)/gi)) {
|
|
606
|
+
if (!code.some(([a, b]) => match.index >= a && match.index < b)) out.push(match[1].toLowerCase());
|
|
607
|
+
}
|
|
608
|
+
return out;
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
// ../../hosted-hub/src/store/notifications.ts
|
|
612
|
+
var NOTIFICATION_READS = s("SELECT person, notification_id FROM notification_reads");
|
|
613
|
+
var NOTIFICATIONS = s("SELECT message_id, person FROM notifications");
|
|
614
|
+
var names = (text, { person, names: names2 }) => {
|
|
615
|
+
const known = new Set([person, ...names2].map((n) => n.toLowerCase()));
|
|
616
|
+
return mentionTokens(text).some((t) => known.has(t));
|
|
617
|
+
};
|
|
618
|
+
var record = (id, person) => s("INSERT OR IGNORE INTO notifications (message_id, person) SELECT ?, ? WHERE EXISTS (SELECT 1 FROM messages WHERE id = ?)", id, person, id);
|
|
619
|
+
var notificationFor = (messageId2, kind, text, notify) => notify && kind === "agent" && names(text, notify) ? [record(messageId2, notify.person)] : [];
|
|
620
|
+
|
|
548
621
|
// ../../hosted-hub/src/store/subagents.ts
|
|
549
622
|
var UP = `up(session_id, parent) AS (
|
|
550
623
|
SELECT session_id, parent FROM subagent_links WHERE session_id = ?
|
|
@@ -596,6 +669,14 @@ var PENDING_REQUESTS_READ = s(`SELECT r.id, r.session_id, r.thread_id, r.bot, r.
|
|
|
596
669
|
// ../../hosted-hub/src/store/workspace-state.ts
|
|
597
670
|
var LIVE_TURNS_READ = s(`SELECT thread_id,bot,started_at,reply_text,activity FROM turns WHERE status IN ${OPEN_TURN_STATUSES} ORDER BY started_at`);
|
|
598
671
|
|
|
672
|
+
// ../../hosted-hub/src/store/attachments.ts
|
|
673
|
+
var ATTACHMENTS_READ = s("SELECT message_id, upload_id, name FROM message_attachments ORDER BY message_id, position");
|
|
674
|
+
var unseenBy = (bot, thread, mid) => {
|
|
675
|
+
const end = `COALESCE((SELECT rowid FROM messages WHERE id = ${mid}), 9223372036854775807)`;
|
|
676
|
+
return `a.message_id = e.id AND e.thread_id = ${thread} AND e.author <> ${bot} AND e.rowid < ${end}
|
|
677
|
+
AND e.rowid > COALESCE((SELECT MAX(p.rowid) FROM deliveries dd JOIN messages p ON p.id = dd.message_id WHERE p.thread_id = e.thread_id AND dd.bot = ${bot} AND p.rowid < ${end}), 0)`;
|
|
678
|
+
};
|
|
679
|
+
|
|
599
680
|
// ../../hosted-hub/src/store/threads.ts
|
|
600
681
|
var SUMMARY_READ = s("SELECT scope,text,by,at FROM summaries");
|
|
601
682
|
|
|
@@ -820,7 +901,7 @@ __export(external_exports, {
|
|
|
820
901
|
properties: () => _properties,
|
|
821
902
|
property: () => _property,
|
|
822
903
|
readonly: () => readonly,
|
|
823
|
-
record: () =>
|
|
904
|
+
record: () => record2,
|
|
824
905
|
refine: () => refine,
|
|
825
906
|
regex: () => _regex,
|
|
826
907
|
regexes: () => regexes_exports,
|
|
@@ -17263,14 +17344,14 @@ function rewriteKeyNames(ctx) {
|
|
|
17263
17344
|
bySchema.set(entry.schema, entry);
|
|
17264
17345
|
}
|
|
17265
17346
|
const rewrites = /* @__PURE__ */ new Map();
|
|
17266
|
-
for (const
|
|
17267
|
-
const seen = ctx.seen.get(
|
|
17268
|
-
const
|
|
17269
|
-
if (!
|
|
17347
|
+
for (const record4 of pendingRecords.get(ctx) ?? []) {
|
|
17348
|
+
const seen = ctx.seen.get(record4);
|
|
17349
|
+
const names2 = (seen?.def ?? seen?.schema)?.propertyNames;
|
|
17350
|
+
if (!names2 || names2 === true || rewrites.has(names2))
|
|
17270
17351
|
continue;
|
|
17271
|
-
const rewritten = stringifyKeyNames(bySchema,
|
|
17272
|
-
if (rewritten !==
|
|
17273
|
-
rewrites.set(
|
|
17352
|
+
const rewritten = stringifyKeyNames(bySchema, names2, /* @__PURE__ */ new Set());
|
|
17353
|
+
if (rewritten !== names2)
|
|
17354
|
+
rewrites.set(names2, rewritten);
|
|
17274
17355
|
}
|
|
17275
17356
|
if (!rewrites.size)
|
|
17276
17357
|
return;
|
|
@@ -17732,7 +17813,7 @@ __export(schemas_exports2, {
|
|
|
17732
17813
|
preprocess: () => preprocess,
|
|
17733
17814
|
promise: () => promise,
|
|
17734
17815
|
readonly: () => readonly,
|
|
17735
|
-
record: () =>
|
|
17816
|
+
record: () => record2,
|
|
17736
17817
|
refine: () => refine,
|
|
17737
17818
|
set: () => set,
|
|
17738
17819
|
strictObject: () => strictObject,
|
|
@@ -18834,7 +18915,7 @@ var ZodRecord = /* @__PURE__ */ $constructor("ZodRecord", (inst, def) => {
|
|
|
18834
18915
|
inst.keyType = def.keyType;
|
|
18835
18916
|
inst.valueType = def.valueType;
|
|
18836
18917
|
});
|
|
18837
|
-
function
|
|
18918
|
+
function record2(keyType, valueType, params) {
|
|
18838
18919
|
if (!valueType || !valueType._zod) {
|
|
18839
18920
|
return new ZodRecord({
|
|
18840
18921
|
type: "record",
|
|
@@ -19309,7 +19390,7 @@ var stringbool = (...args) => _stringbool({
|
|
|
19309
19390
|
}, ...args);
|
|
19310
19391
|
function json(params) {
|
|
19311
19392
|
const jsonSchema = lazy(() => {
|
|
19312
|
-
return union([string2(params), number2(), boolean2(), _null3(), array(jsonSchema),
|
|
19393
|
+
return union([string2(params), number2(), boolean2(), _null3(), array(jsonSchema), record2(string2(), jsonSchema)]);
|
|
19313
19394
|
});
|
|
19314
19395
|
return jsonSchema;
|
|
19315
19396
|
}
|
|
@@ -25246,14 +25327,14 @@ function rewriteKeyNames2(ctx) {
|
|
|
25246
25327
|
bySchema.set(entry.schema, entry);
|
|
25247
25328
|
}
|
|
25248
25329
|
const rewrites = /* @__PURE__ */ new Map();
|
|
25249
|
-
for (const
|
|
25250
|
-
const seen = ctx.seen.get(
|
|
25251
|
-
const
|
|
25252
|
-
if (!
|
|
25330
|
+
for (const record4 of pendingRecords2.get(ctx) ?? []) {
|
|
25331
|
+
const seen = ctx.seen.get(record4);
|
|
25332
|
+
const names2 = (seen?.def ?? seen?.schema)?.propertyNames;
|
|
25333
|
+
if (!names2 || names2 === true || rewrites.has(names2))
|
|
25253
25334
|
continue;
|
|
25254
|
-
const rewritten = stringifyKeyNames2(bySchema,
|
|
25255
|
-
if (rewritten !==
|
|
25256
|
-
rewrites.set(
|
|
25335
|
+
const rewritten = stringifyKeyNames2(bySchema, names2, /* @__PURE__ */ new Set());
|
|
25336
|
+
if (rewritten !== names2)
|
|
25337
|
+
rewrites.set(names2, rewritten);
|
|
25257
25338
|
}
|
|
25258
25339
|
if (!rewrites.size)
|
|
25259
25340
|
return;
|
|
@@ -26084,7 +26165,7 @@ var ZodRecord2 = /* @__PURE__ */ $constructor2("ZodRecord", (inst, def) => {
|
|
|
26084
26165
|
inst.keyType = def.keyType;
|
|
26085
26166
|
inst.valueType = def.valueType;
|
|
26086
26167
|
});
|
|
26087
|
-
function
|
|
26168
|
+
function record3(keyType, valueType, params) {
|
|
26088
26169
|
if (!valueType || !valueType._zod) {
|
|
26089
26170
|
return new ZodRecord2({
|
|
26090
26171
|
type: "record",
|
|
@@ -26354,7 +26435,7 @@ function superRefine2(fn, params) {
|
|
|
26354
26435
|
|
|
26355
26436
|
// ../wire/src/common.ts
|
|
26356
26437
|
var maybe = (schema) => schema.nullish();
|
|
26357
|
-
var map2 = (id, value) =>
|
|
26438
|
+
var map2 = (id, value) => record3(string5(), value).meta({ id });
|
|
26358
26439
|
|
|
26359
26440
|
// ../wire/src/live.ts
|
|
26360
26441
|
var TaskRow = object2({
|
|
@@ -26999,6 +27080,11 @@ var SESSION_WORK_DELIVERY = `busy.accepted_at IS NOT NULL AND busy.failed_at IS
|
|
|
26999
27080
|
WHERE td.delivery_id = busy.id AND t.status NOT IN ('streaming','cancelling'))`;
|
|
27000
27081
|
var SESSION_BUSY = `s.ended_at IS NULL AND EXISTS (SELECT 1 FROM deliveries busy
|
|
27001
27082
|
WHERE busy.session_id = s.id AND ${SESSION_WORK_DELIVERY})`;
|
|
27083
|
+
var PENDING_FROM = `SELECT d.id, d.message_id, d.session_id, d.bot, m.thread_id, t.title, m.author, m.author_kind, m.text, m.status, m.status_from, m.metadata, d.steer,
|
|
27084
|
+
EXISTS (SELECT 1 FROM deliveries a WHERE a.session_id = d.session_id AND a.accepted_at IS NOT NULL) AS session_started,
|
|
27085
|
+
s.ended_at IS NOT NULL AS session_ended, ${onLocal("d.bot")} AS on_local,
|
|
27086
|
+
(SELECT json_group_array(json_object('id', a.upload_id, 'name', a.name, 'size', a.size)) FROM (SELECT * FROM message_attachments WHERE message_id = m.id ORDER BY position) a) AS attachments
|
|
27087
|
+
FROM deliveries d JOIN messages m ON m.id = d.message_id JOIN threads t ON t.id = m.thread_id JOIN sessions s ON s.id = d.session_id`;
|
|
27002
27088
|
var TASK_CARD = `(SELECT CASE WHEN json_array_length(json_extract(t.activity, '$.taskCard.tasks')) > 0 THEN json_extract(t.activity, '$.taskCard') END
|
|
27003
27089
|
FROM turns t WHERE t.id = m.turn_id AND m.author_kind = 'agent' AND t.status NOT IN ${OPEN_TURN_STATUSES}
|
|
27004
27090
|
AND m.rowid = (SELECT MAX(x.rowid) FROM messages x WHERE x.turn_id = m.turn_id))`;
|
|
@@ -27010,12 +27096,18 @@ var DELIVERY_STATUS = `CASE WHEN d.accepted_at IS NOT NULL OR ${LINKED} THEN COA
|
|
|
27010
27096
|
AND r.created_at <= COALESCE((SELECT t.started_at FROM turn_deliveries td JOIN turns t ON t.id = td.turn_id WHERE td.delivery_id = d.id), d.accepted_at) LIMIT 1),
|
|
27011
27097
|
CASE WHEN ${LINKED} THEN 'seen' ELSE 'delivered' END)
|
|
27012
27098
|
WHEN d.failed_at IS NOT NULL THEN 'failed' WHEN d.revoked_at IS NOT NULL THEN 'skipped'
|
|
27013
|
-
WHEN d.held_at IS NOT NULL THEN CASE d.held_scope WHEN 'bot' THEN 'queued until free' ELSE 'queued' END
|
|
27099
|
+
WHEN d.held_at IS NOT NULL THEN CASE d.held_scope WHEN 'bot' THEN 'queued until free' ELSE 'queued' END
|
|
27100
|
+
WHEN ${onLocal("d.bot")} AND EXISTS (SELECT 1 FROM local_runner WHERE id = 1 AND device IS NOT NULL AND attachments = 0)
|
|
27101
|
+
AND (EXISTS (SELECT 1 FROM message_attachments o WHERE o.message_id = d.message_id)
|
|
27102
|
+
OR EXISTS (SELECT 1 FROM message_attachments a, messages e WHERE ${unseenBy("d.bot", "(SELECT thread_id FROM messages WHERE id = d.message_id)", "d.message_id")}))
|
|
27103
|
+
THEN 'waiting: the Mac app running this bot is too old to carry images; update it'
|
|
27104
|
+
ELSE 'pending' END`;
|
|
27014
27105
|
|
|
27015
27106
|
// ../../hosted-hub/src/store/fold.ts
|
|
27016
27107
|
var FOLD_STATE_SQL = `SELECT s.id, s.thread_id, s.bot, COALESCE(f.folded_index, -1) AS folded_index, (SELECT json_group_array(name) FROM (SELECT name FROM bots ORDER BY position)) AS roster,
|
|
27017
27108
|
(SELECT json_group_array(bot) FROM (${PARTICIPANTS("s.thread_id")})) AS participants,
|
|
27018
27109
|
(SELECT d.message_id FROM deliveries d WHERE d.bot = s.bot AND d.held_at IS NOT NULL AND d.held_paused IS NOT 1 AND d.accepted_at IS NULL AND d.failed_at IS NULL AND d.revoked_at IS NULL ORDER BY d.rowid LIMIT 1) AS held,
|
|
27110
|
+
(SELECT json_object('person', person, 'names', json(names)) FROM human_notify) AS notify,
|
|
27019
27111
|
(SELECT json_object('status', t.status, 'id', t.id, 'text', t.reply_text, 'lastStep', json(t.last_step), 'activity', json(t.activity)) FROM turns t WHERE t.session_id = s.id AND t.status IN ${OPEN_TURN_STATUSES}
|
|
27020
27112
|
ORDER BY t.started_at DESC LIMIT 1) AS open_turn
|
|
27021
27113
|
FROM sessions s LEFT JOIN session_folds f ON f.session_id = s.id WHERE s.id = ?`;
|
|
@@ -27026,6 +27118,7 @@ function foldState(row) {
|
|
|
27026
27118
|
roster: JSON.parse(String(row.roster)),
|
|
27027
27119
|
participants: JSON.parse(String(row.participants)),
|
|
27028
27120
|
held: row.held == null ? null : String(row.held),
|
|
27121
|
+
notify: row.notify ? JSON.parse(String(row.notify)) : null,
|
|
27029
27122
|
foldedIndex: Number(row.folded_index),
|
|
27030
27123
|
open: row.open_turn ? JSON.parse(String(row.open_turn)) : null
|
|
27031
27124
|
};
|
|
@@ -27156,6 +27249,7 @@ function fold(state, chunks, now = Date.now()) {
|
|
|
27156
27249
|
SELECT ?, ?, ?, 'agent', ?, ?, ? WHERE ? <> ''
|
|
27157
27250
|
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));
|
|
27158
27251
|
log("message.created", { messageId: messageId2, author: session.bot, authorKind: "agent" }, IF_INSERTED);
|
|
27252
|
+
stmts.push(...notificationFor(messageId2, "agent", text, state.notify ?? void 0));
|
|
27159
27253
|
const to = recipients(state.roster, text, { name: session.bot, kind: "agent" }, session.thread, state.participants);
|
|
27160
27254
|
stmts.push(...routingStatements(messageId2, session.thread, to, at, { by: session.bot, joins: true }));
|
|
27161
27255
|
deliver.push(messageId2);
|